home *** CD-ROM | disk | FTP | other *** search
- NAME mssfil
- ; File MSSFIL.ASM
- include mssdef.h
- ; Copyright (C) 1985, 1993, Trustees of Columbia University in the
- ; City of New York. Permission is granted to any individual or institution
- ; to use this software as long as it is not sold for profit. This copyright
- ; notice must be retained. This software may not be included in commercial
- ; products without written permission of Columbia University.
- ;
- ; Edit history:
- ; 27 August 1992 version 3.13
- ; 6 Sept 1991 version 3.11
- ; 2 March 1991 version 3.10
- ; Last edit 25 May 1993
-
- public buff, gofil, ptchr, gtchr, getfil, gtnfil, doenc, dodec
- public encbuf, decbuf, diskio, auxfile, fparse, prtasz, prtscr
- public strlen, strcat, strcpy, tfilsz, templp, latin1, charids
- public L1cp437, L1cp850, L1cp860, L1cp863, L1cp865, unique
- public load, cplatin, goopen, latininv, protlist
-
- SIchar equ 0fh
- SOchar equ 0eh
- DLE equ 10h
-
- data segment
- extrn flags:byte, trans:byte, denyflg:word, dosnum:word
- extrn oldkbt:word, oldper:word, filtst:byte, rdbuf:byte, fsta:byte
- extrn curdsk:byte
-
- ermes4 db 'Unable to make unique name',0
- ermes9 db 'Printer not ready',0
- erms12 db 'Unable to create file ',0
- erms13 db 'Error writing output file',0
- infms5 db 'Renaming file to $'
- infms6 db cr,lf,'?Unable to open file$'
- asmsg db ' as $'
- crlf db cr,lf,'$'
- printer db 'PRN',0
- screen db 'CON',0
- loadhlp db 'filename$'
- ; DOS special chars allowed in filenames
- spchar2 db '$', 26h, 23h, 40h, 21h, 25h, 27H, '(', ')', '-', 7bh, 7dh
- db 5fh, 5eh, 7eh, 60h
- spc2len equ $-spchar2
-
- textctl db cr,lf,tab,bell,ff,ctlz ; controls allowed in text files
- textctlen equ $-textctl
- even
- filflg db 0 ; input buffer has data, if non-zero
- rptct db 1 ; number of times it's repeated
- dblbyte db 0 ; first of two bytes in a pair
- dblbyteflg db 0 ; non-zero if processing second byte of pair
- DLEseen db 0
- shiftstate db 0 ; locking shift (0 = unshifted, 80h = shifted)
- decoutp dw 0 ; ptr to proc to dump decode output buffer
- encinp dw 0 ; ptr to proc to refill encode input buffer
- dchrcnt dw 0 ; number of chars in the decode file buffer
- echrcnt dw 0 ; number of chars in the encode file buffer
- dbufpnt dw 0 ; position in file buffer, decoder
- ebufpnt dw 0 ; position in file buffer, encoder
- ;
- db 0 ; this MUST directly preceed decbuf, jpnwrite
- decbuf db 512 dup (0) ; decoding source buffer
- db 0 ; safety for possible null terminator
- encbuf db 512 dup (0) ; encoding source buffer
- db 0 ; safety for possible null terminator
- protlist db 32 dup (0) ; list of protected control codes (if = 0)
-
- tfilsz dw 0,0 ; bytes transferred (double word qty)
- nmoflg db 0 ; have override filename, if non-zero
- templp db 65 dup (?) ; temp for local path part
- templf db 14 dup (?) ; temp for local filename part
- temprp db 65 dup (?) ; temp for remote path part
- temprf db 14 dup (?) ; temp for remote filename part
- auxfile db 65 dup (?) ; auxillary filename for general use
- diskio filest <> ; ditto, for ordinary file transfers
- buff db buffsz dup (?) ; use as our Disk Transfer Area
- havdot db 0 ; dot-found status in verify
- unum dw 0 ; unique filename generation number
- temp dw 0
- ; charids: table of transfer char-set idents
- charids dw 7 ; qty, pointers to char set idents
- dw chtrans,chlatin1,chlatin2,chhebiso,chcyrill,chjapan,chjapanold
- chtrans db 1,'A' ; Transparent: char count, ident
- chlatin1 db 6,'I6/100' ; Latin1: char count, ident
- chlatin2 db 6,'I6/101' ; Latin2: char count, ident
- chhebiso db 6,'I6/138' ; Hebrew-ISO: char count, ident
- chcyrill db 6,'I6/144' ; Cyrillic: char count, ident
- chjapan db 9,'I14/87/13' ; Japanese-EUC: char count, ident (new)
- chjapanold db 7,'I14/87E' ; Japanese-EUC: char count, ident (obsolete)
- ; end of charids info
- ;loadtab db 1 ; LOAD command table
- ; mkeyw 'Transfer-character-set',0
- ;
- ;filtab macro
- ; cnt = 128
- ; rept 128 ; 128 idenity entries
- ; db cnt ; initialize table to 128 .. 255
- ; cnt = cnt + 1
- ; endm
- ;endm
- ;
- ;userin equ this byte ; LOAD command
- ; filtab ; init table to idenity
- ;namein db 20 dup (0) ; name of the character set
- ;userout equ this byte
- ; filtab ; init table to idenity
- ;nameout db 20 dup (0) ; name of the character set
- ;tblptr dw 0 ; LOAD command
- ;xlines dw 0 ; LOAD command
- ;linecnt dw 0 ; LOAD command
- ;badvalue db cr,lf,'?Bad value on line $'
-
- ; Translation tables for byte codes 0a0h..0ffh to map ISO 8859-1 to Code Pages
- ; Codes 00h-1fh are 7-bit controls (C0), codes 20h..7eh are ASCII, 7fh DEL is
- ; considered to be a control code, 80h..9fh are 8-bit controls (C1).
- ; Each table is 96 translatable bytes followed by the table size (96), the
- ; ISO announcer ident ('A' and a null here); LATIN5/Cyrillic uses 'L'.
- ; The decimal tables are from Frank da Cruz working with the formal IBM docs.
- ; from ISO 8859-1 Latin-1 to Code Page
- ; to CP437 United States
- L1cp437 db 80h,81h,82h,83h, 84h,85h,86h,87h ; column 8
- db 88h,89h,8ah,8bh, 8ch,8dh,8eh,8fh
- db 90h,91h,92h,93h, 94h,95h,96h,97h ; column 9
- db 98h,99h,9ah,9bh, 9ch,9dh,9eh,9fh
- db 20h,0adh,9bh,9ch, 0fh,9dh,7ch,15h ; column 10
- db 22h,40h,0a6h,0aeh, 0aah,0c4h,3fh,2dh
- db 0f8h,0f1h,0fdh,33h, 27h,0e6h,14h,0fah ; column 11
- db 2ch,31h,0a7h,0afh, 0ach,0abh,3fh,0a8h
- db 41h,41h,41h,41h, 8eh,8fh,92h,80h ; column 12
- db 45h,90h,45h,45h, 49h,49h,49h,49h
- db 44h,0a5h,4fh,4fh, 4fh,4fh,99h,58h ; column 13
- db 4fh,55h,55h,55h, 9ah,59h,3fh,0e1h
- db 85h,0a0h,83h,61h, 84h,86h,91h,87h ; column 14
- db 8ah,82h,88h,89h, 8dh,0a1h,8ch,8bh
- db 3fh,0a4h,95h,0a2h, 93h,6fh,94h,0f6h ; column 15
- db 6fh,97h,0a3h,96h, 81h,79h,3fh,98h
- db 96,'A',0 ; 96 byte set, letter ident
-
- ; to CP850 Multilingual
- L1cp850 db 80h,81h,82h,83h, 84h,85h,86h,87h ; column 8
- db 88h,89h,8ah,8bh, 8ch,8dh,8eh,8fh
- db 90h,91h,92h,93h, 94h,95h,96h,97h ; column 9
- db 98h,99h,9ah,9bh, 9ch,9dh,9eh,9fh
- db 20h,0adh,0bdh,9ch, 0cfh,0beh,0ddh,0f5h ; column 10
- db 0f9h,0b8h,0a6h,0aeh, 0aah,0f0h,0a9h,0eeh
- db 0f8h,0f1h,0fdh,0fch, 0efh,0e6h,0f4h,0fah ; column 11
- db 0f7h,0fbh,0a7h,0afh, 0ach,0abh,0f3h,0a8h
- db 0b7h,0b5h,0b6h,0c7h, 8eh,8fh,92h,80h ; column 12
- db 0d4h,90h,0d2h,0d3h, 0deh,0d6h,0d7h,0d8h
- db 0d1h,0a5h,0e3h,0e0h, 0e2h,0e5h,99h,9eh ; column 13
- db 9dh,0ebh,0e9h,0eah, 9ah,0edh,0e8h,0e1h
- db 85h,0a0h,83h,0c6h, 84h,86h,91h,87h ; column 14
- db 8ah,82h,88h,89h, 8dh,0a1h,8ch,8bh
- db 0d0h,0a4h,95h,0a2h, 93h,0e4h,94h,0f6h ; column 15
- db 9bh,97h,0a3h,96h, 81h,0ech,0e7h,98h
- db 96,'A',0 ; 96 byte set, letter ident
-
- ; to CP860 Portugal
- L1cp860 db 80h,81h,82h,83h, 84h,85h,86h,87h ; column 8
- db 88h,89h,8ah,8bh, 8ch,8dh,8eh,8fh
- db 90h,91h,92h,93h, 94h,95h,96h,97h ; column 9
- db 98h,99h,9ah,9bh, 9ch,9dh,9eh,9fh
- db 20h,0adh,9bh,9ch, 0fh,59h,7ch,15h ; column 10
- db 22h,40h,0a6h,0aeh, 0aah,0c4h,3fh,2dh
- db 0f8h,0f1h,0fdh,33h, 27h,0e6h,14h,0fah ; column 11
- db 2ch,31h,0a7h,0afh, 0ach,0abh,3fh,0a8h
- db 91h,86h,8fh,8eh, 41h,41h,41h,80h ; column 12
- db 92h,90h,89h,45h, 8bh,98h,49h,49h
- db 44h,0a5h,0a9h,9fh, 8ch,99h,4fh,58h ; column 13
- db 4fh,9dh,96h,55h, 9ah,59h,3fh,0e1h
- db 85h,0a0h,83h,84h, 61h,61h,61h,87h ; column 14
- db 8ah,82h,88h,65h, 8dh,0a1h,69h,69h
- db 3fh,0a4h,95h,0a2h, 93h,94h,6fh,0f6h ; column 15
- db 6fh,97h,0a3h,75h, 81h,79h,3fh,79h
- db 96,'A',0 ; 96 byte set, letter ident
-
- ; to CP861 Iceland
- L1cp861 db 80h,0fch,82h,83h, 84h,85h,86h,87h ; column 8
- db 88h,89h,8ah,8bh, 8ch,8dh,8eh,8fh
- db 90h,91h,92h,93h, 94h,95h,96h,97h ; column 9
- db 98h,99h,9ah,9bh, 9ch,9dh,9eh,9fh
- db 20h,0adh,43h,9ch, 0fh,59h,7ch,15h ; column 10
- db 22h,3fh,0a6h,0aeh, 0aah,16h,3fh,2dh
- db 0f8h,0f1h,0fdh,33h, 27h,0e6h,14h,0fah ; column 11
- db 2ch,31h,3fh,0afh, 0ach,0abh,3fh,0a8h
- db 41h,0a4h,41h,41h, 8eh,8fh,92h,80h ; column 12
- db 45h,90h,45h,45h, 49h,0a5h,49h,49h
- db 8bh,4eh,4fh,0a6h, 4fh,4fh,99h,58h ; column 13
- db 9dh,55h,0a7h,55h, 9ah,97h,8dh,0e1h
- db 85h,0a0h,83h,61h, 84h,86h,91h,87h ; column 14
- db 8ah,82h,88h,89h, 69h,0a1h,69h,69h
- db 8ch,6eh,6fh,0a2h, 93h,6fh,94h,0f6h ; column 15
- db 9bh,75h,0a3h,96h, 81h,98h,95h,79h
- db 96,'A',0 ; 96 byte set, letter ident
-
- ; to CP863 Canada-French
- L1cp863 db 80h,81h,82h,83h, 84h,85h,86h,87h ; column 8
- db 88h,89h,8ah,8bh, 8ch,8dh,8eh,8fh
- db 90h,91h,92h,93h, 94h,95h,96h,97h ; column 9
- db 98h,99h,9ah,9bh, 9ch,9dh,9eh,9fh
- db 20h,3fh,9bh,9ch, 98h,59h,0a0h,8fh ; column 10
- db 0a4h,40h,61h,0aeh, 0aah,0c4h,3fh,0a7h
- db 0f8h,0f1h,0fdh,0a6h, 0a1h,0e6h,86h,0fah ; column 11
- db 0a5h,31h,6fh,0afh, 0ach,0abh,0adh,3fh
- db 8eh,41h,84h,41h, 41h,41h,41h,80h ; column 12
- db 91h,90h,92h,94h, 49h,49h,0a8h,95h
- db 44h,4eh,4fh,4fh, 99h,4fh,4fh,58h ; column 13
- db 4fh,9dh,55h,9eh, 9ah,59h,3fh,0e1h
- db 85h,61h,83h,61h, 61h,61h,61h,87h ; column 14
- db 8ah,82h,88h,89h, 69h,69h,8ch,8bh
- db 3fh,6eh,6fh,0a2h, 93h,6fh,6fh,0f6h ; column 15
- db 6fh,97h,0a3h,96h, 81h,79h,3fh,79h
- db 96,'A',0 ; 96 byte set, letter ident
- ; to CP865 Norway
- L1cp865 db 80h,81h,82h,83h, 84h,85h,86h,87h ; column 8
- db 88h,89h,8ah,8bh, 8ch,8dh,8eh,8fh
- db 90h,91h,92h,93h, 94h,95h,96h,97h ; column 9
- db 98h,99h,9ah,9bh, 9ch,9dh,9eh,9fh
- db 20h,0adh,3fh,9ch, 0afh,59h,7ch,15h ; column 10
- db 22h,40h,0a6h,0aeh, 0aah,0c4h,3fh,0c4h
- db 0f8h,0f1h,0fdh,33h, 27h,0e6h,14h,0fah ; column 11
- db 2ch,31h,0a7h,03fh, 0ach,0abh,3fh,0a8h
- db 41h,41h,41h,41h, 8eh,8fh,92h,80h ; column 12
- db 45h,90h,45h,45h, 49h,49h,49h,49h
- db 44h,0a5h,4fh,4fh, 4fh,4fh,99h,58h ; column 13
- db 9dh,55h,55h,55h, 9ah,59h,3fh,0e1h
- db 85h,0a0h,83h,61h, 84h,86h,91h,87h ; column 14
- db 8ah,82h,88h,89h, 8dh,0a1h,8ch,8bh
- db 3fh,0a4h,95h,0a2h, 93h,6fh,94h,0f6h ; column 15
- db 9bh,97h,0a3h,96h, 81h,79h,3fh,98h
- db 96,'A',0 ; 96 byte set, letter ident
- ; Latin2 to CP852
- L2cp852 db 174,175,176,177,178,179,180,185,186,187,188,191,192,193,194,195
- db 196,197,200,201,202,203,204,205,206,217,218,219,220,223,240,254
- db 255,164,244,157,207,149,151,245,249,230,184,155,141,170,166,189
- db 248,165,242,136,239,150,152,243,247,231,173,156,171,241,167,190
- db 232,181,182,198,142,145,143,128,172,144,168,211,183,214,215,210
- db 209,227,213,224,226,138,153,158,252,222,233,235,154,237,221,225
- db 234,160,131,199,132,146,134,135,159,130,169,137,216,161,140,212
- db 208,228,229,162,147,139,148,246,253,133,163,251,129,236,238,250
- db 96,'B',0 ; 96 byte set, letter ident
-
- ; Hebrew-ISO to Code Page 862, GLeft
- HIcp862 db 158,159,160,161,162,163,164,165,166,167,168,169,173,176,177,178
- db 179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194
- db 255,195,155,156,196,157,197,198,199,200,201,174,170,202,203,204
- db 248,241,253,206,207,230,208,249,209,210,246,175,172,171,211,212
- db 213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228
- db 229,231,232,233,234,235,236,237,238,239,240,242,243,244,245,205
- db 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143
- db 144,145,146,147,148,149,150,151,152,153,154,247,250,251,252,254
- db 96,'H',0
-
- ; Latin5 to CP866
- L5cp866 db 80h,81h,82h,83h, 84h,85h,86h,87h ; column 8
- db 88h,89h,8ah,8bh, 8ch,8dh,8eh,8fh
- db 90h,91h,92h,93h, 94h,95h,96h,97h ; column 9
- db 98h,99h,9ah,9bh, 9ch,9dh,9eh,9fh
- db 0ffh,0f0h,3fh,3fh, 0f2h,53h,49h,4fh ; column 10
- db 4ah,3fh,3fh,48h, 4bh,2dh,0f6h,3fh
- db 80h,81h,82h,83h, 84h,85h,86h,87h ; column 11
- db 88h,89h,8ah,8bh, 8ch,8dh,8eh,8fh
- db 90h,91h,92h,93h, 94h,95h,96h,97h ; column 12
- db 98h,99h,9ah,9bh, 9ch,9dh,9eh,9fh
- db 0a0h,0a1h,0a2h,0a3h,0a4h,0a5h,0a6h,0a7h ; column 13
- db 0a8h,0a9h,0aah,0abh,0ach,0adh,0aeh,0afh
- db 0e0h,0e1h,0e2h,0e3h,0e4h,0e5h,0e6h,0e7h ; column 14
- db 0e8h,0e9h,0eah,0ebh,0ech,0edh,0eeh,0efh
- db 0fch,0f1h,3fh,3fh, 0f3h,73h,69h,0f5h ; column 15
- db 6ah,3fh,3fh,68h, 6bh,15h,0f7h,3fh
- db 96,'L',0 ; 96 byte set, Latin5/Cyrillic
-
-
- ;yl143[] /* Latin-1 to IBM Code Page 437 */
- ; Although the IBM CDRA does not include an official translation between CP437
- ; and ISO Latin Alphabet 1, it does include an official, invertible
- ; translation between CP437 and CP850 (page 196), and another from CP850 to
- ; Latin-1 (CP819) (page 153). This translation was obtained with a two-step
- ; process based on those tables.
-
- iL1cp437 db 199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197
- db 201,230,198,244,246,242,251,249,255,214,220,162,163,165,215,159
- db 225,237,243,250,241,209,170,186,191,174,172,189,188,161,171,187
- db 155,156,157,144,151,193,194,192,169,135,128,131,133,248,216,147
- db 148,153,152,150,145,154,227,195,132,130,137,136,134,129,138,164
- db 240,208,202,203,200,158,205,206,207,149,146,141,140,166,204,139
- db 211,223,212,210,245,213,181,254,222,218,219,217,253,221,175,180
- db 173,177,143,190, 20, 21,247,184,176,168,183,185,179,178,142,160
- db 96,'A',0 ; 96 byte set, letter ident
-
- ;yl185[] /* Latin-1 to IBM Code Page 850 */
- ; This is IBM's official invertible translation. Reference: IBM Character
- ; Data Representation Architecture (CDRA), Level 1, Registry, SC09-1291-00
- ; (1990), p.152. (Note: Latin-1 is IBM Code Page 00819.)
- iL1cp850 db 186,205,201,187,200,188,204,185,203,202,206,223,220,219,254,242
- db 179,196,218,191,192,217,195,180,194,193,197,176,177,178,213,159
- db 255,173,189,156,207,190,221,245,249,184,166,174,170,240,169,238
- db 248,241,253,252,239,230,244,250,247,251,167,175,172,171,243,168
- db 183,181,182,199,142,143,146,128,212,144,210,211,222,214,215,216
- db 209,165,227,224,226,229,153,158,157,235,233,234,154,237,232,225
- db 133,160,131,198,132,134,145,135,138,130,136,137,141,161,140,139
- db 208,164,149,162,147,228,148,246,155,151,163,150,129,236,231,152
- db 96,'A',0 ; 96 byte set, letter ident
-
- ; invertable Latin-1 to CP861
- iL1cp861 db 199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197
- db 201,230,198,244,246,242,251,249,255,214,220,162,163,165,215,159
- db 225,237,243,250,241,209,170,186,191,174,172,189,188,161,171,187
- db 155,156,157,144,151,193,194,192,169,135,128,131,133,248,216,147
- db 148,164,152,150,145,154,227,195,132,130,137,136,134,165,138,164
- db 139,208,202,166,200,158,205,206,157,149,167,141,140,151,141,139
- db 211,223,212,210,245,213,181,254,222,218,219,217,253,221,175,180
- db 140,177,143,190, 20, 21,247,184,155,168,183,185,179,152,149,160
- db 96,'A',0 ; 96 byte set, letter ident
-
- ; 128 byte translation tables from Code Pages to ISO 8859-1 Latin1 or Latin5
- ; For GRight only (high bit set).
- ; from Code Page 437
- cp437L1 db 0c7h,0fch,0e9h,0e2h, 0e4h,0e0h,0e5h,0e7h ; column 8
- db 0eah,0ebh,0e8h,0efh, 0eeh,0ech,0c4h,0c5h
- db 0c9h,0e6h,0c6h,0f4h, 0f6h,0f2h,0fbh,0f9h ; column 9
- db 0ffh,0d6h,0dch,0a2h, 0a3h,0a5h,3fh,3fh
- db 0e1h,0edh,0f3h,0fah, 0f1h,0d1h,0aah,0bah ; column 10
- db 0bfh,3fh,0ach,0bdh, 0bch,0a1h,0abh,0bbh
- db 16 dup (3fh) ; column 11
- db 16 dup (3fh) ; column 12
- db 16 dup (3fh) ; column 13
- db 3fh,0dfh, 4 dup (3fh), 0b5h,3fh ; column 14
- db 5 dup(3fh), 0f8h,3fh,3fh
- db 3fh,0b1h, 4 dup (3fh), 0f7h,3fh ; column 15
- db 0b0h,0b7h,0b7h,3fh,3fh, 0b2h,3fh,3fh
- ; from Code Page 850
- cp850L1 db 0c7h,0fch,0e9h,0e2h, 0e4h,0e0h,0e5h,0e7h ; column 8
- db 0eah,0ebh,0e8h,0efh, 0eeh,0ech,0c4h,0c5h
- db 0c9h,0e6h,0c6h,0f4h, 0f6h,0f2h,0fbh,0f9h ; column 9
- db 0ffh,0d6h,0dch,0f8h, 0a3h,0d8h,0d7h,3fh
- db 0e1h,0edh,0f3h,0fah, 0f1h,0d1h,0aah,0bah ; column 10
- db 0bfh,0aeh,0ach,0bdh, 0bch,0a1h,0abh,0bbh
- db 5 dup (3fh), 0c1h,0c2h,0c0h ; column 11
- db 0a9h, 4 dup (3fh), 0a2h,0a5h,3fh
- db 6 dup (3fh),0e3h,0c3h, 7 dup (3fh),0a4h ; column 12
- db 0f0h,0d0h,0cah,0cbh, 0c8h,0b9h,0cdh,0ceh ; column 13
- db 0cfh, 4 dup (3fh), 0a6h,0cch,3fh
- db 0d3h,0dfh,0d4h,0d2h, 0f5h,0d5h,0b5h,0feh ; column 14
- db 0deh,0dah,0dbh,0d9h, 0fdh,0ddh,0afh,0b4h
- db 0adh,0b1h,3dh,0beh, 0b6h,0a7h,0f7h,0b8h ; column 15
- db 0b0h,0a8h,0b7h,0b9h, 0b3h,0b2h,3fh,20h
-
- ; from Code Page 860
- cp860L1 db 0c7h,0fch,0e9h,0e2h, 0e3h,0e0h,0c1h,0e7h ; column 8
- db 0eah,0cah,0e8h,0cch, 0d4h,0ech,0c3h,0c2h
- db 0c9h,0c0h,0c8h,0f4h, 0f5h,0f2h,0dah,0f9h ; column 9
- db 0cdh,0d5h,0dch,0a2h, 0a3h,0d9h,3fh,0d3h
- db 0e1h,0edh,0f3h,0fah, 0f1h,0d1h,0aah,0bah ; column 10
- db 0bfh,0d2h,0ach,0bdh, 0bch,0a1h,0abh,0bbh
- db 16 dup (3fh) ; column 11
- db 16 dup (3fh) ; column 12
- db 16 dup (3fh) ; column 13
- db 3fh,0dfh, 4 dup (3fh), 0b5h,3fh ; column 14
- db 5 dup(3fh), 0f8h,3fh,3fh
- db 3fh,0b1h, 4 dup (3fh), 0f7h,3fh ; column 15
- db 0b0h,0b7h,0b7h,3fh, 3fh,0b2h,3fh,3fh
-
- ; from Code Page 861
- cp861L1 db 0c7h,0fch,0e9h,0e2h, 0e4h,0e0h,0e5h,0e7h ; column 8
- db 0eah,0ebh,0e8h,0d0h, 0f0h,0deh,0c4h,0c5h
- db 0c9h,0e6h,0c6h,0f4h, 0f6h,0feh,0fbh,0ddh ; column 9
- db 0fdh,0d6h,0dch,0f8h, 0a3h,0d8h,3fh,3fh
- db 0e1h,0edh,0f3h,0fah, 0c1h,0cdh,0d3h,0dah ; column 10
- db 0bfh,3fh,0ach,0bdh, 0bch,0a1h,0abh,0bbh
- db 16 dup (3fh) ; column 11
- db 16 dup (3fh) ; column 12
- db 16 dup (3fh) ; column 13
- db 3fh,0dfh, 4 dup (3fh), 0b5h,3fh ; column 14
- db 5 dup(3fh), 0f8h,3fh,3fh
- db 3fh,0b1h, 4 dup (3fh), 0f7h,3fh ; column 15
- db 0b0h,0b7h,0b7h,3fh,3fh, 0b2h,3fh,3fh
-
- ; from Code Page 863
- cp863L1 db 0c7h,0fch,0e9h,0e2h, 0c2h,0e0h,0b6h,0e7h ; column 8
- db 0eah,0ebh,0e8h,0efh, 0eeh,3dh,0c0h,0a7h
- db 0c9h,0c8h,0cah,0f4h, 0cbh,0cfh,0fbh,0f9h ; column 9
- db 0a4h,0d4h,0dch,0a2h, 0a3h,0d9h,0dbh,3fh
- db 0a6h,0b4h,0f3h,0fah, 0a8h,0b8h,0b3h,0afh ; column 10
- db 0ceh,3fh,0ach,0bdh, 0bch,0beh,0abh,0bbh
- db 16 dup (3fh) ; column 11
- db 16 dup (3fh) ; column 12
- db 16 dup (3fh) ; column 13
- db 3fh,0dfh, 4 dup (3fh), 0b5h,3fh ; column 14
- db 5 dup(3fh), 0f8h,3fh,3fh
- db 3fh,0b1h, 4 dup (3fh), 0f7h,3fh ; column 15
- db 0b0h,0b7h,0b7h,3fh, 3fh,0b2h,3fh,3fh
- ; from Code Page 865
- cp865L1 db 0c7h,0fch,0e9h,0e2h, 0e4h,0e0h,0e5h,0e7h ; column 8
- db 0eah,0ebh,0e8h,0efh, 0eeh,0ech,0c4h,0c5h
- db 0c9h,0e6h,0c6h,0f4h, 0f6h,0f2h,0fbh,0f9h ; column 9
- db 0ffh,0d6h,0dch,0f8h, 0a3h,0d8h,3fh,3fh
- db 0e2h,0edh,0f3h,0fah, 0f1h,0d1h,0aah,0bah ; column 10
- db 0bfh,3fh,0ach,0bdh, 0bch,0a1h,0abh,0a4h
- db 16 dup (3fh) ; column 11
- db 16 dup (3fh) ; column 12
- db 16 dup (3fh) ; column 13
- db 3fh,0dfh, 4 dup (3fh), 0b5h,3fh ; column 14
- db 5 dup(3fh), 0f8h,3fh,3fh
- db 3fh,0b1h, 4 dup (3fh), 0f7h,3fh ; column 15
- db 0b0h,0b7h,0b7h,3fh, 3fh,0b2h,3fh,3fh
- ; from Code Page 852 to LATIN2
- cp852L2 db 199,252,233,226,228,249,230,231,179,235,213,245,238,172,196,198
- db 201,197,229,244,246,165,181,166,182,214,220,171,187,163,215,232
- db 225,237,243,250,161,177,174,190,202,234,173,188,200,186,128,129
- db 130,131,132,133,134,193,194,204,170,135,136,137,138,175,191,139
- db 140,141,142,143,144,145,195,227,146,147,148,149,150,151,152,164
- db 240,208,207,203,239,210,205,206,236,153,154,155,156,222,217,157
- db 211,223,212,209,241,242,169,185,192,218,224,219,253,221,254,180
- db 158,189,178,183,162,167,247,184,176,168,255,251,216,248,159,160
-
- ; Code Page 862 to Hebrew-ISO
- cp862HI db 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239
- db 240,241,242,243,244,245,246,247,248,249,250,162,163,165,128,129
- db 130,131,132,133,134,135,136,137,138,139,172,189,188,140,171,187
- db 141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156
- db 157,158,159,161,164,166,167,168,169,170,173,174,175,223,179,180
- db 182,184,185,190,191,192,193,194,195,196,197,198,199,200,201,202
- db 203,204,205,206,207,208,181,209,210,211,212,213,214,215,216,217
- db 218,177,219,220,221,222,186,251,176,183,252,253,254,178,255,160
-
- ; from Code Page 866 to LATIN5
- cp866L5 db 0b0h,0b1h,0b2h,0b3h, 0b4h,0b5h,0b6h,0b7h ; column 8
- db 0b8h,0b9h,0bah,0bbh, 0bch,0bdh,0beh,0bfh
- db 0c0h,0c1h,0c2h,0c3h, 0c4h,0c5h,0c6h,0c7h ; column 9
- db 0c8h,0c9h,0cah,0cbh, 0cch,0cdh,0ceh,0cfh
- db 0d0h,0d1h,0d2h,0d3h, 0d4h,0d5h,0d6h,0d7h ; column 10
- db 0d8h,0d9h,0dah,0dbh, 0dch,0ddh,0deh,0dfh
- db 16 dup (3fh) ; column 11
- db 16 dup (3fh) ; column 12
- db 16 dup (3fh) ; column 13
- db 0e0h,0e1h,0e2h,0e3h, 0e4h,0e5h,0e6h,0e7h ; column 14
- db 0e8h,0e9h,0eah,0ebh, 0ech,0edh,0eeh,0efh
- db 0a1h,0f1h,0a4h,0f4h, 0a7h,0f7h,0aeh,0feh ; column 15
- db 4 dup (3fh), 0f0h,3fh,3fh,0a0h
-
- ;y43l1[] /* IBM Code Page 437 to Latin-1 */
- ; This table is the inverse of yl143[].
- icp437L1 db 199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197
- db 201,230,198,244,246,242,251,249,255,214,220,162,163,165,215,159
- db 225,237,243,250,241,209,170,186,191,174,172,189,188,161,171,187
- db 155,156,157,144,151,193,194,192,169,135,128,131,133,248,216,147
- db 148,153,152,150,145,154,227,195,132,130,137,136,134,129,138,164
- db 240,208,202,203,200,158,205,206,207,149,146,141,140,166,204,139
- db 211,223,212,210,245,213,181,254,222,218,219,217,253,221,175,180
- db 173,177,143,190, 20, 21,247,184,176,168,183,185,179,178,142,160
-
- ;y85l1[] /* IBM Code Page 850 to Latin-1 */
- ; This is from IBM CDRA page 153. It is the inverse of yl185[].
- icp850L1 db 199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197
- db 201,230,198,244,246,242,251,249,255,214,220,248,163,216,215,159
- db 225,237,243,250,241,209,170,186,191,174,172,189,188,161,171,187
- db 155,156,157,144,151,193,194,192,169,135,128,131,133,162,165,147
- db 148,153,152,150,145,154,227,195,132,130,137,136,134,129,138,164
- db 240,208,202,203,200,158,205,206,207,149,146,141,140,166,204,139
- db 211,223,212,210,245,213,181,254,222,218,219,217,253,221,175,180
- db 173,177,143,190,182,167,247,184,176,168,183,185,179,178,142,160
-
- ;y86l1[] /* IBM Code Page 861 to Latin-1 */
- ; This table is the inverse of yl186[].
- icp861L1 db 199,252,233,226,228,224,229,231,234,235,232,208,240,222,196,197
- db 201,230,198,244,246,254,251,221,253,214,220,248,163,216,215,159
- db 225,237,243,250,193,205,211,218,191,174,172,189,188,161,171,187
- db 155,156,157,144,151,193,194,192,169,135,128,131,133,248,216,147
- db 148,153,152,150,145,154,227,195,132,130,137,136,134,129,138,164
- db 240,208,202,203,200,158,205,206,207,149,146,141,140,166,204,139
- db 211,223,212,210,245,213,181,254,222,218,219,217,253,221,175,180
- db 173,177,143,190, 20, 21,247,184,176,168,183,185,179,178,142,160
- data ends
-
- code segment
- extrn decout:near, isfile:near, newfn:near, comnd:near, atoi:near
- extrn ermsg:near, clrfln:near, frpos:near, kbpr:near, perpr:near
-
- assume cs:code, ds:data, es:nothing
-
- ; Set register BX to the offset of the ISO Latin-1 table appropriate to the
- ; currently active Code Page. Defaults to CP437 if no CP found.
- LATIN1 proc near
- push ax
- mov ax,flags.chrset
- mov bx,offset L1cp437 ; assume CP437
- cmp ax,437 ; current Code Page is 437?
- je latin1x ; e = yes
- mov bx,offset L1cp850 ; assume CP850
- cmp ax,850 ; current Code Page is 850?
- je latin1x ; e = yes
- mov bx,offset L1cp860 ; assume CP860
- cmp ax,860 ; current Code Page is 860?
- je latin1x ; e = yes
- mov bx,offset L1cp861 ; assume CP861
- cmp ax,861 ; current Code Page is 861?
- je latin1x ; e = yes
- mov bx,offset L2cp852 ; assume CP852
- cmp ax,852 ; current Code Page is 852?
- je latin1x ; e = yes
- mov bx,offset HIcp862 ; assume CP862
- cmp ax,862 ; current Code Page is 862?
- je latin1x ; e = yes
- mov bx,offset L1cp863 ; assume CP863
- cmp ax,863 ; current Code Page is 863?
- je latin1x ; e = yes
- mov bx,offset L1cp865 ; assume CP865
- cmp ax,865 ; current Code Page is 865?
- je latin1x ; e = yes
- mov bx,offset L5cp866 ; assume CP866
- cmp ax,866 ; current Code Page is 866?
- je latin1x ; e = yes
- ; mov bx,offset userin ; user loadable incoming table
- ; cmp ax,1 ; User-defined table?
- ; je latin1x ; e = yes
- mov bx,offset L1cp437 ; default to CP437
- latin1x:pop ax
- ret
- LATIN1 endp
-
- ; Call after LATIN1. Revise BX to point to invertible tables rather than
- ; readable translation tables.
- latininv proc near
- cmp trans.xchri,0 ; readable (vs invertible)?
- je latinvx ; e = yes, do nothing
- cmp bx,offset L1cp437 ; this table in use?
- jne latinv1 ; ne = no
- mov bx,offset iL1cp437 ; use invertible instead
- ret
- latinv1:cmp bx,offset L1cp850 ; this table in use?
- jne latinv2 ; ne = no
- mov bx,offset iL1cp850 ; use invertible instead
- ret
- latinv2:cmp bx,offset L1cp861 ; this table?
- jne latinvx ; ne = no
- mov bx,offset iL1cp861 ; use invertible instead
- latinvx:ret
- latininv endp
-
- ; Set BX to offset of table for Code Page to ISO 8859-1 Latin1/Latin5
- cplatin proc near
- push ax
- mov ax,flags.chrset
- mov bx,offset cp437L1 ; assume CP437
- cmp ax,437 ; current Code Page is 437?
- je cplatx ; e = yes
- mov bx,offset cp850L1 ; assume CP850
- cmp ax,850 ; current Code Page is 850?
- je cplatx ; e = yes
- mov bx,offset cp860L1 ; assume CP860
- cmp ax,860 ; current Code Page is 860?
- je cplatx ; e = yes
- mov bx,offset cp861L1 ; assume CP861
- cmp ax,861 ; current Code Page is 861?
- je cplatx ; e = yes
- mov bx,offset cp852L2 ; assume CP852
- cmp ax,852 ; current Code Page is 852?
- je cplatx ; e = yes
- mov bx,offset cp862HI ; assume CP862
- cmp ax,862 ; current Code Page is 862?
- je cplatx ; e = yes
- mov bx,offset cp863L1 ; assume CP863
- cmp ax,863 ; current Code Page is 863?
- je cplatx ; e = yes
- mov bx,offset cp865L1 ; assume CP865
- cmp ax,865 ; current Code Page is 865?
- je cplatx ; e = yes
- mov bx,offset cp866L5 ; assume CP866 for LATIN5
- cmp ax,866 ; corrent Code Page is 866?
- je cplatx ; e = yes
- ; mov bx,offset userout ; user loadable outgoing table
- ; cmp ax,1 ; User-table?
- ; je cplatx ; e = yes
- mov bx,offset cp437L1 ; default to CP437
- cplatx: pop ax
- ret
- cplatin endp
-
- ; Call after CPLATIN. Revise BX to point to invertible tables rather than
- ; readable translation tables.
- cpinvert proc near
- cmp trans.xchri,0 ; readable (vs invertible)?
- je cpinverx ; e = yes, do nothing
- cmp bx,offset cp437L1 ; this table in use?
- jne cpinver1 ; ne = no
- mov bx,offset icp437L1 ; use invertible instead
- ret
- cpinver1:cmp bx,offset cp850L1 ; this table in use?
- jne cpinver2 ; ne = no
- mov bx,offset icp850L1 ; use invertible instead
- ret
- cpinver2:cmp bx,offset cp861L1 ; this table in use?
- jne cpinverx ; ne = no
- mov bx,offset icp861L1 ; use invertible instead
- cpinverx:ret
- cpinvert endp
-
- ; Output the chars in a packet, called only by receiver code.
- ; Enter with SI equal to pktinfo structure pointer.
- PTCHR: mov decoutp,offset outbuf ; routine to call when buffer gets full
- jmp short decode
-
-
- ; Dodecoding.
- ; Decode packet to buffer decbuf. Overflow of decbuf yields error ???
- ; Modifies regs BX, CX.
- ; Enter with SI equal to pktinfo structure pointer.
- dodec proc near
- push ax ; save reg
- mov ah,dblbyteflg ; preserve state
- mov al,dblbyte
- push ax
- mov al,shiftstate
- mov ah,DLEseen
- push ax
- mov dblbyteflg,0 ; init decode as doubles
- mov shiftstate,0 ; init shift states
- mov DLEseen,0 ; init escape
- mov decoutp,offset dnulr ; routine to dump buffer (null)
- call decode
- pop ax
- mov shiftstate,al ; restore decoder state
- mov DLEseen,ah
- pop ax
- mov dblbyteflg,ah
- mov dblbyte,al
- push bx
- mov bx,dbufpnt ; next char position
- mov byte ptr [bx],0 ; null terminator
- pop bx
- pop ax
- ret
- dodec endp
-
- dnulr: ret ; dummy buffer emptier
-
- ; Enter with [si].datlen = length of data, [si].datadr = dw address of data,
- ; DECOUTP = pointer to routine which writes output buffer
- ; Returns DBUFPNT = pointer to output buffer address (offset part).
- ; Trans.lshift is non-zero if locking shift encoding is active.
- ; DLEseen is non-zero if a DLE char (Control-P) is decoded while locking shift
- ; is active; under these circumstances DLE escapes DLE, SI, and SO to be
- ; data characters. Under locking shift rules SO (Control-N) shifts high bit
- ; data to non-high bit data (and we thus reverse this); SI (Control-O)
- ; cancels SO.
- ; Dblbyteflg is non-zero if the first of a byte pair has been obtained while
- ; performing Japanese translation; dblbyte is the first byte of the pair.
- ; All packets are decoded except I, S, and A types.
- ; Flushes output buffer before returning.
- ; Returns carry clear if success, otherwise carry set
- decode proc near
- push si
- push di
- push es
- push dx
- push ds
- pop es
- cld ; forward direction
- mov dchrcnt,length decbuf ; size of output buffer
- mov dbufpnt,offset decbuf ; decoded data placed here pending output
- mov cx,[si].datlen ; length of source buffer data
- les si,[si].datadr ; source buffer address to es:[si]
- mov di,dbufpnt ; destination of data
- mov bl,trans.squote ; regular quote char
- xor dh,dh ; assume no quote char
- cmp trans.ebquot,'N' ; any 8-bit quoting?
- je decod1 ; e = no quoting
- cmp trans.ebquot,'Y' ; or not doing it?
- je decod1 ; e = no need to quote
- mov dh,trans.ebquot ; otherwise use 8-bit quote char
-
- decod1: mov rptct,1 ; reset repeat count
- or cx,cx ; any more chars in source?
- jg decod2 ; g = yes
- jmp decod6 ; else, we're through
- decod2: mov al,es:[si] ; pick up a char
- inc si
- dec cx ; count number left
- cmp al,trans.rptq ; repeat quote char?
- jne dcod2a ; ne = no, continue processing it
- or al,al ; doing repeat quoting? (0 if no)
- jz dcod2a ; z = no, skip this part
- mov al,es:[si] ; get the size
- inc si
- dec cx ; modify buffer count
- sub al,20H ; make count numeric
- mov rptct,al ; remember how many repetitions
- mov al,es:[si] ; get the char to repeat
- inc si
- dec cx ; modify buffer count
-
- dcod2a: xor ah,ah ; assume no 8-bit quote char
- cmp al,dh ; is this the 8-bit quot char?
- jne decod3 ; ne = no
- mov al,es:[si] ; yes, get the real character
- inc si
- dec cx ; decrement # chars in packet
- mov ah,80H ; turn on high bit
- decod3: cmp al,bl ; quote char?
- jne decod4 ; ne = no, proceed
- mov al,es:[si] ; get the quoted character
- inc si
- dec cx ; decrement # of chars in packet
- or ah,al ; save parity (combine with prefix)
- and ax,807fh ; only parity in ah, remove it in al
- cmp al,bl ; quote char?
- je decod4 ; e = yes, just go write it out
- cmp al,dh ; 8-bit quote char?
- je decod4 ; e = yes, just go write it out
- cmp al,trans.rptq ; repeat quote character?
- je decod4 ; e = yes, just write it out
- cmp al,3fh ; char less than '?' ?
- jb decod4 ; b = yes; leave it intact
- cmp al,5fh ; char greater than '_' ?
- ja decod4 ; a = yes; leave it alone
- add al,40H ; make it a control char again
- and al,7FH ; modulo 128 (includes DEL)
- decod4: xor ah,shiftstate ; modify high bit by shiftstate
- or al,ah ; or in parity
-
- cmp trans.lshift,lock_disable ; locking shift disabled?
- je decod5 ; e = yes
- mov ah,al
- xor ah,shiftstate ; adjust high bit by shift state
- cmp ah,DLE ; DLE?
- jne dcod4c ; ne = no
- cmp DLEseen,0 ; has DLE been escaped (by DLE)?
- je dcod4b ; e = no, make this the escape
- mov DLEseen,0 ; unescape now
- jmp short decod5 ; process the literal DLE
- ; handle repeat counted DLE's
- dcod4b: shr rptct,1 ; divide by two, carry has lsb
- rcl DLEseen,1 ; pickup carry bit if odd number
- jmp short decod5 ; write the DLE's
-
- dcod4c: cmp DLEseen,0 ; DLE prefix seen?
- mov DLEseen,0 ; clear it now too
- jne decod5 ; ne = yes, prefixed, do literal
- cmp ah,SIchar ; SI?
- jne dcod4d ; ne = no
- mov shiftstate,0 ; say exiting shifted state
- jmp decod1 ; nothing to write
- dcod4d: cmp ah,SOchar ; SO?
- jne decod5 ; ne = no
- mov shiftstate,80h ; say entering shifted state
- jmp decod1 ; nothing to write
-
- decod5: push cx
- mov cl,rptct ; repeat count
- xor ch,ch
- or cl,cl
- jle decod5c ; le = nothing to do (94 max)
- cmp cx,dchrcnt ; needed vs space available
- jbe decod5a ; be = enough space for rptct chars
- mov cx,dchrcnt ; insufficient space, do dchrcnt
- decod5a:sub rptct,cl ; reduce number left to be written
- sub dchrcnt,cx ; reduce output free space
- pushf ; save sub status flags
- shr cx,1
- jnc decod5b ; nc = an even number
- mov [di],al ; store the odd byte
- inc di
- jcxz decod5d ; z = nothing else to write
- decod5b:mov ah,al ; make a copy for word writes
- push bx ; source is es:[si], dest is ds:[di]
- push es ; save and swap ds and es
- push ds
- mov bx,es
- pop es ; old ds to es
- push ds ; restore
- mov ds,bx ; old es to ds
- rep stosw ; store cx words
- pop ds
- pop es
- pop bx
- decod5d:popf ; recover flags from sub dchrcnt,cx
- jg decod5c ; g = space remaining in output buffer
- push dx ; flush output buffer
- push bx
- push ax ; save the char
- push es
- call decoutp ; output the buffer
- pop es
- pop ax ; recover repeated char
- pop bx
- pop dx
- jc decod7 ; c = error if disk is full
- mov di,dbufpnt
- pop cx
- jmp short decod5 ; see if more chars need be written
- decod5c:pop cx ; recover main loop counter
- jmp decod1 ; get next source character
-
- decod6: mov dbufpnt,di ; flush buffer before exiting decode
- push cx
- push es
- call decoutp ; flush output buffer before final ret
- pop es
- decod7: pop cx
-
- pop dx
- pop es
- pop di
- pop si
- ret ; return successfully if carry clear
- decode endp
-
- outbuf proc near ; output decbuf, reset bufpnt & chrcnt
- mov cx,length decbuf ; get full size of buffer
- sub cx,dchrcnt ; minus space remaining = # to write
- jg outbu2 ; g = something to do
- jmp outbf1
- outbu2: mov dx,offset decbuf ; address of buffer
- cmp trans.xtype,1 ; File Type Binary?
- je outbu5 ; e = yes, no translation
- cmp flags.destflg,1 ; disk destination?
- je outbu5 ; e = yes, DOS will do it
- cmp flags.eofcz,0 ; end on Control-Z?
- je outbu5 ; e = no
- push cx ; else map Control-Z to space
- push di
- mov di,seg decbuf
- mov es,di ; data to es
- mov di,dx ; scan buffer es:di, cx chars worth
- mov al,ctlz ; look for Control-Z
- cld
- outbu3: repne scasb
- jne outbu4 ; ne = found no Control-Z's
- mov byte ptr [di-1],' ' ; replace Control-Z with space
- jcxz outbu4 ; z = examined all chars
- jmp short outbu3 ; until examined everything
- outbu4: pop di
- pop cx
- ; Character set translation section
- outbu5: cmp trans.xtype,1 ; File Type Binary?
- je outbu7 ; e = yes, no translation
- cmp trans.xchset,xfr_xparent ; Transfer Transparent?
- je outbu7 ; e = yes, no translation
- cmp trans.xchset,xfr_japanese ; Japanese-EUC?
- jne outbu5a ; ne = no
- call jpnwrite ; do special decoding
- jmp outbu7
- outbu5a:push cx
- push si
- push di
- mov di,seg decbuf
- mov es,di
- call latin1 ; set BX to xfr char set to CP table
- call latininv ; select invertable or readable set
- mov si,offset decbuf ; scan this buffer
- mov di,si
- cld
- outbu6: lodsb ; get a char
- test al,80h ; GRight?
- jnz outbu6a ; nz = yes
- cmp bx,offset iL1cp437 ; using invertable Latin1 to CP437?
- jne outbu6c ; ne = no
- cmp ah,127 ; 127 goes to 28?
- jne outbu6e ; ne = no
- mov al,28 ; 127 to 28
- jmp short outbu6b
- outbu6e:cmp al,21 ; special case?
- ja outbu6b ; a = no
- cmp al,20 ; special case?
- jb outbu6b ; b = no
- mov ah,al
- mov al,244 ; 20 to 244
- cmp ah,21 ; special case?
- jne outbu6b ; ne = no
- mov al,245 ; preset one answer
- je outbu6b ; e = yes, 21 to 245
- mov al,244 ; 22 to 244
- jmp short outbu6b
- outbu6c:cmp bx,offset iL1cp850 ; using invertible Latin1 to CP850?
- jne outbu6b ; ne = no
- cmp al,26 ; special case?
- jne outbu6d ; ne = no
- mov al,127 ; 26 to 127
- jmp outbu6b
- outbu6d:cmp al,127 ; special case?
- jne outbu6b ; ne = no
- mov al,28 ; 127 to 28
- jmp short outbu6b
- outbu6a:and al,not 80h ; strip high bit
- xlatb ; translate via bx table
- outbu6b:stosb ; store char
- loop outbu6 ; do all concerned
- pop di
- pop si
- pop cx
-
- outbu7: push bx
- mov bx,diskio.handle ; file handle
- mov ah,write2 ; write cx bytes
- int dos
- pop bx
- jc outbf0 ; c set means writing error
- cmp ax,cx ; did we write all the bytes?
- je outbf1 ; e = yes
- push bx
- mov bx,offset decbuf
- add bx,ax ; look at break character
- cmp byte ptr [bx],ctlz ; ended on Control-Z?
- pop bx
- je outbf1 ; e = yes, say no error
- outbf0: mov dx,offset erms13 ; Error writing device
- cmp flags.xflg,0 ; writing to screen?
- jne outbf0a ; ne = yes
- cmp flags.destflg,0 ; writing to printer?
- jne outbf0a ; ne = no
- mov dx,offset ermes9 ; Printer not ready message
- outbf0a:call ermsg
- stc ; return failure
- ret
-
- outbf1: add tfilsz,cx ; count received chars
- adc tfilsz+2,0
- add fsta.frbyte,cx
- adc fsta.frbyte+2,0
- test flags.remflg,dserial ; serial mode display?
- jnz outb11 ; nz = yes, skip kbyte and % displays
- cmp flags.xflg,0 ; receiving to screen?
- jne outb11 ; ne = yes
- call kbpr ; display kilobytes done
- call perpr ; display percentage done
- outb11: mov dbufpnt,offset decbuf ; address for beginning
- mov dchrcnt,length decbuf ; size of empty buffer
- clc ; return success
- ret
- outbuf endp
-
- ; Japanese file transfer section (Hirofumi Fujii, keibun@kek.ac.jp)
- ; Reread buffer decbuf to convert from transfer character set
- ; Japanese-EUC into Shift-JIS (Code Page 932). Double char translation state
- ; is maintained across file buffers. Init dblbyte to 0 before each new file.
- ; Returns registers
- ; cx number of bytes written in the buffer
- ; dx address of the output buffer
- ; this points decbuf or decbuf-1, depending on dblbyteflg
- ; Output is otherwise written over the input. [rewritten by jrd]
- jpnwrite proc near ; [HF] write Japanese to file
- push si ; decbuf is read/written
- push di ; cx has incoming/outgoing byte count
- push bx ; dblbyte has earlier first byte
- push es ; dblbyteflg is state from prev call
- mov dx,ds
- mov es,dx
- cld ; restore state from previous call
- mov dl,dblbyteflg ; state, non-zero if doing second byte
- mov ah,dblbyte ; and first byte from previous read
- mov si,offset decbuf ; read/write this buffer
- mov di,si ; set the address for write
- mov bx,si ; save for computing output buf length
- or dl,dl ; carry-in of a double byte char?
- jz jpnwri1 ; z = no
- dec di ; start output one byte before decbuf
- dec bx ; adjust the start address
- jpnwri1:lodsb ; get a byte
- or dl,dl ; processing 2nd byte of a pair?
- jnz jpnwri3 ; nz = yes, do second byte processor
- ; first byte processor
- cmp al,80h ; 8th bit on?
- jb jpnwri5 ; b = no, this is a single char
- cmp al,8eh ; JIS X 0201 Katakana prefix?
- je jpnwri2 ; e = yes, is first of two chars
- cmp al,0a1h ; JIS X 0208 Kanji ?
- jb jpnwri5 ; b = no, is single char
- cmp al,0feh
- ja jpnwri5 ; a = no, is single char
- jpnwri2:mov ah,al ; save first of two chars
- mov dl,1 ; say need second char of pair
- jmp short jpnwri6 ; read second byte
- ; process second char of two byte pair
- jpnwri3:cmp ah,8eh ; was first char JIS X 0201 Katakana?
- jne jpnwri4 ; ne = no
- or al,80h ; make sure 8th bit is on
- jmp short jpnwri5 ; write one char
- jpnwri4:call jpnxtof ; xfer -> file char code conversion
- xchg ah,al
- stosb ; write first byte
- xchg ah,al ; and second byte
- jpnwri5:stosb ; write a char
- xor dl,dl ; clear multi-byte counter
- jpnwri6:loop jpnwri1
- mov dblbyteflg,dl ; save state info
- mov dblbyte,ah ; and the first byte of a pair
- sub di,bx ; find number of chars written
- mov cx,di ; return new count in CX
- mov dx,bx ; return new buffer address for write
- pop es ; can be decbuf - 1 if carry-in of dbl
- pop bx
- pop di
- pop si
- clc
- ret
- jpnwrite endp
-
- ; Transfer character code (EUC) to file character code (Shift-JIS) converter.
- ; input AH: 1st byte of EUC code
- ; AL: 2nd byte of EUC code
- ; output AH: 1st byte of Shift-JIS code
- ; AL: 2nd byte of Shift-JIS code
- ; From EUC to Shift-JIS
- ; code1 = (EUC_code1 & 0x7f);
- ; code2 = (EUC_code2 & 0x7f);
- ; if( code1 & 1)
- ; code2 += 0x1f;
- ; else
- ; code2 += 0x7d;
- ; if( code2 >= 0x7f ) code2++;
- ; code1 = ((code1 - 0x21) >> 1) + 0x81;
- ; if( code1 > 0x9f ) code1 += 0x40;
- ; [ fputc( code1, file ); fputc( code2, file ); ]
- ;
- jpnxtof proc near
- and ax,7f7fh ; mask both 8-th bits
- test ah,1
- jz jpnxtof1
- add al,1fh
- jmp short jpnxtof2
- jpnxtof1:add al,7dh
- jpnxtof2:cmp al,7fh
- jb jpnxtof3
- inc al
- jpnxtof3:sub ah,21h
- shr ah,1
- add ah,81h
- cmp ah,9fh
- jbe jpnxtof4
- add ah,40h
- jpnxtof4:ret
- jpnxtof endp
-
- ; Get chars from file, encode them to pktinfo structure pointed to by si
-
- gtchr: mov [si].datlen,0 ; say no output data yet
- cmp filflg,0 ; is there anything in the buffer?
- jne gtchr0 ; ne = yes, use that material first
- call inbuf ; do initial read from source
- jc gtchr1 ; c = no more chars, go return EOF
- gtchr0: mov encinp,offset inbuf ; buffer refiller routine
- jmp short encode
-
- gtchr1: mov [si].datlen,0 ; report EOF
- mov flags.eoflag,1 ; say eof
- stc ; return failure
- ret
-
- ; Do encoding.
- ; Enter with CX = data size, source of data is encbuf, si is pktinfo ptr.
- ; Writes output to area pointed to by [si].datadr.
- ; Returns char count in cx and [si].datlen with carry clear if success,
- ; else carry set if overflow.
- ; SI is preserved
- doenc: clc
- jcxz doen0 ; cx = 0 means nothing to encode
- mov ah,dblbyteflg ; preserve state
- mov al,dblbyte
- push ax
- mov al,shiftstate ; locking shift state
- mov ah,DLEseen ; DLE state
- push ax ; save
- mov dblbyteflg,0 ; init encode as doubles
- mov shiftstate,0 ; init shift states
- mov DLEseen,0
- mov echrcnt,cx ; number of bytes of source data
- mov ebufpnt,offset encbuf ; source of data
- mov encinp,offset nulref ; null routine for refilling buffer
- call encode ; make a packet with size in AX
- mov cx,ax
- pop ax ; restore state
- mov shiftstate,al
- mov DLEseen,ah
- pop ax
- mov dblbyteflg,ah
- mov dblbyte,al
- doen0: ret
-
- nulref: mov echrcnt,0 ; no data to return
- stc
- ret
-
- ; encode - writes data portion of kermit packet into [[si].datadr].
- ; expects encinp to contain the address of a routine to refill the buffer,
- ; chrcnt to be the # of chars in the buffer, trans.maxdat to contain
- ; the maximum size of the data packet, ebufpnt to contain a pointer to
- ; the source of the characters, and [si].datadr to be output address.
- ; Trans.lshift is non-zero if locking shift encoding is active.
- ; While locking shift is active DLE escapes DLE, SI, and SO to be
- ; data characters. Under locking shift rules SO (Control-N) shifts high bit
- ; data to non-high bit data; SI (Control-O) cancels SO. Shiftstate is
- ; 0 for non-shifted state, 80h for shifted state.
- ; Dblbyteflg is non-zero if the first of a byte pair has been obtained while
- ; performing Japanese translation; dblbyte is the first byte of the pair.
- ; Returns: AX = the number of characters actually written to the buffer
- ; All packets except I, S, and A types are encoded.
- ; Packet space is precomputed allowing for prefixes other than locking shifts.
- ; Returns carry clear for success, carry set otherwise.
-
- encode proc near
- push es
- push si ; save caller's si
- mov cx,trans.maxdat ; maximum packet size
- les di,[si].datadr ; address of output buffer to es:[di]
- mov temp,di ; remember output buffer start address
- mov si,ebufpnt ; pointer into source buffer
- mov dl,trans.rquote ; send quote char
- xor dh,dh ; assume no 8-bit quoting
- mov al,trans.ebquot ; 8-bit quote
- cmp al,'N' ; refusing 8-bit quoting?
- je encod10 ; e = yes
- cmp al,'Y' ; or can but won't?
- je encod10 ; e = yes, else specific char
- mov dh,0ffh ; remember we have to do 8-bit quotes
- ; top of read loop
- encod10:or cx,cx ; any space left in output buffer?
- jge encod11 ; ge = yes
- mov ax,di ; current output location
- sub ax,temp ; minus start of buffer, ret cnt in AX
- mov ebufpnt,si ; update pointer into source buffer
- pop si ; restore caller's si
- pop es
- mov [si].datlen,ax
- clc ; success
- ret
-
- encod11:cmp echrcnt,0 ; any data in buffer?
- jg encod20 ; g = yes, skip over buffer refill
- push es
- call encinp ; get another buffer full
- pop es
- jnc encod14 ; nc = success
-
- encod12:pop si ; restore user's si
- sub di,temp ; minus start of buffer
- or di,di ; buffer empty?
- jz encod13 ; z = yes
- mov ax,di ; report size encoded
- mov [si].datlen,ax
- pop es
- clc ; success
- ret ; return success
- encod13:xor ax,ax ; empty buffer
- mov flags.eoflag,1 ; set eof flag
- mov filflg,al ; nothing in input buffer
- mov [si].datlen,ax
- pop es
- stc ; failure
- ret ; return failure
-
- encod14:mov si,ebufpnt ; update position in source buffer
- cmp echrcnt,0 ; any characters returned?
- je encod12 ; e = none, assume eof
-
- encod20:cld ; forward direction
- lodsb
- dec echrcnt ; decrement input count
- mov ah,al
- and ah,80h ; keep high bit in ah
- mov rptct,1 ; say have one copy of this char
- cmp al,'Z'-40H ; is this a control-Z?
- jne encd30 ; ne = no, skip eof-processing
- cmp flags.eofcz,0 ; is a Control-Z an end of file?
- je encd30 ; e = no
- cmp trans.xtype,1 ; file type binary?
- je encd30 ; e = yes, send as is
- mov flags.eoflag,1 ; yes, set eof flag
- mov filflg,0 ; say no more source data in buffer
- mov echrcnt,0 ; ditto
- jmp short encod12 ; set character count and return
-
- ; analyze current char (al)
- encd30: cmp echrcnt,0 ; doing the last character?
- jle encod40 ; le = yes, there is no next character
- or cx,cx ; space left in output buffer?
- jle encod40a ; le = no, not enough for rpt prefix
- cmp al,[si] ; this is char the same as the next?
- jne encod40 ; no, do this char independently
- cmp trans.rptq,0 ; allowed to do repeat prefixing?
- je encod40 ; e = no
- push cx ; scan for repeats in input buffer
- push bx
- mov cx,echrcnt ; count of bytes left in input buf
- inc cx ; will reread current byte
- cmp cx,94 ; max prefix of 94
- jbe encod31 ; be = ok, else limit scan to 94
- mov cx,94
- encod31:xor bx,bx ; count of copies of this char in buf
- encod32:inc bx
- cmp [si+bx-1],al ; new [si+bx-1] same as current (al)?
- loope encod32 ; e = yes, do all of interest
- cmp bx,3 ; enough repeats to use prefix?
- jae encod33 ; ae = yes
- mov bx,1 ; say do one char
- encod33:mov rptct,bl ; bl is qty repeated overall
- dec bx ; ax = number of extra chars (>1)
- add si,bx ; move forward by repeat group
- sub echrcnt,bx ; input buffer counter too
- pop bx
- pop cx
-
- ; test for locking shift applicability
- encod40:or cx,cx ; enough space left in output buffer?
- jle encod50 ; le = no, not enough for prefix
- cmp trans.lshift,lock_disable ; locking shifts disabled?
- je encod50 ; e = yes, skip this material
- cmp ah,shiftstate ; change of high bit status?
- jne encod41 ; ne = yes
- encod40a:jmp encod50 ; no, stay in same lock state
- ; change of high bit
- encod41:mov bx,echrcnt ; count chars remaining to be read
- add bl,rptct ; add repeat count
- adc bh,0
- cmp bx,4 ; at least 4 more chars to examine?
- jb encod50 ; b = no, not worth a lock change
- cmp rptct,4 ; enough repeats to take short cut?
- jae encod43 ; ae = plenty of repeats
-
- push ax ; look for change of shift state
- push cx
- push si
- mov cl,rptct ; repeat count
- xor ch,ch
- dec cx ; count is one for no repeats
- sub si,cx ; back up over repeated chars
- mov cx,4 ; look ahead 4 chars
- encod42:lodsb ; read ahead
- and al,80h ; pick out high bit
- cmp al,ah ; high bit the same?
- loope encod42 ; loop while same
- pop si
- pop cx
- pop ax
- jne encod50 ; ne = differ, don't change lock
- ; change locking shift state
- encod43:mov es:[di],dl ; insert quote char (#)
- inc di ; adjust output buffer pointer
- dec cx
- push ax
- mov ah,shiftstate ; get current shift state
- xor ah,80h ; toggle shift state
- mov shiftstate,ah ; remember it
- mov al,SIchar+40h ; assume going into unshifted state
- or ah,ah ; to unshifted state now?
- jz encod44 ; z = yes, go to unshifted state
- mov al,SOchar+40h ; say go to shifted state
- encod44:stosb ; put lock char into packet
- dec cx
- pop ax ; recover current character
- ; end of locking shift tests
- encod50:or dh,dh ; doing 8-bit quoting?
- jz encod60 ; z = no, forget this
- cmp trans.lshift,lock_disable ; locking shift disabled?
- je encod57 ; e = yes
- cmp ah,shiftstate ; different than current shift state?
- jne encod58 ; ne = yes, specials will be prefixed
- push ax ; save char (stripped of high bit)
- and al,7fh ; consider high bit controls too
- cmp al,SIchar ; SI (Control-O)?
- je encod53 ; e = yes
- cmp al,SOchar ; SO (Control-N)?
- je encod53 ; e = yes
- cmp al,DLE ; DLE (Control-P)?
- jne encod54 ; ne = no
- encod53:mov al,dl ; stuff a quote (#)
- stosb
- dec cx
- mov al,DLE + 40h ; then a DLE prefix (P)
- stosb
- dec cx ; account for it in buffer size
- encod54:pop ax ; exit with original char in AL
- jmp short encod60 ; no 8-bit prefixing needed here
-
- encod57:cmp ah,shiftstate ; different than current shift state?
- je encod60 ; e = no, don't send quoted form
- encod58:cmp rptct,1 ; doing repeats?
- jbe encod59 ; be = no
- push ax ; do repeat prefixing - save data
- mov al,trans.rptq ; insert repeat prefix char
- stosb
- dec cx ; account for it in buffer size
- mov al,rptct ; get the repeat count
- add al,20h ; make it printable
- stosb ; insert into buffer
- dec cx
- pop ax ; get back the actual character
- encod59:mov bl,trans.ebquot ; get 8-bit quote char
- mov es:[di],bl ; put in packet
- inc di
- dec cx ; decrement # of chars left
- jmp short encod60b
- ; common prefix testing section
- encod60:cmp rptct,1 ; doing repeats?
- jbe encod60b ; be = no
- push ax ; do repeat prefixing - save data
- mov al,trans.rptq ; insert repeat prefix char
- stosb
- dec cx ; account for it in buffer size
- mov al,rptct ; get the repeat count
- add al,20h ; make it printable
- stosb ; insert into buffer
- dec cx
- pop ax ; get back the actual character
-
- encod60b:and al,7fh ; turn off 8th bit in character
- cmp al,' ' ; compare to a space
- jae encod61 ; ae = not a control code
- push bx ; check for unprefixed selections
- mov bl,al ; as 1=7-bit, 80h=8-bit, 81h=both
- xor bh,bh
- mov bl,protlist[bx] ; get 8 and 7 bit encoding rules
- or bl,bl ; anything being excepted from prefix?
- jz encod60a ; z = no
- test bl,ah ; 8-bit unprefixed?
- jnz encod60a ; nz = yes
- or ah,ah ; is it a 7-bit char in reality?
- jnz encod60a ; nz = no
- and bl,1 ; text 7 bit unprefixed
- encod60a:pop bx
- jz encod64 ; z = char needs quoting
- jmp short encod67 ; store char as-is
- encod61:
- cmp al,del ; delete?
- je encod64 ; e = yes, go quote it
- cmp al,dl ; quote char?
- je encod65 ; e = yes, go add it
- or dh,dh ; doing 8-bit quoting?
- jz encod62 ; z = no, don't translate it
- cmp al,trans.ebquot ; 8-bit quote char?
- je encod65 ; e = yes, just output with quote
- encod62:cmp trans.rptq,0 ; doing repeat prefixing?
- je encod67 ; e = no, don't check for quote char
- cmp al,trans.rptq ; repeat quote character?
- je encod65 ; e = yes, then quote it
- jmp short encod67 ; else don't quote it
- ; control code section
- encod64:xor al,40h ; control char, uncontrollify
- encod65:mov es:[di],dl ; insert control quote char
- inc di
- dec cx
- encod67:or al,ah ; restore high bit, if stripped
- or dh,dh ; doing eight bit quoting?
- jz encod68 ; z = no, retain high bit
- and al,not 80h ; strip high bit
- encod68:stosb
- dec cx ; decrement output buffer counter
- jmp encod10 ; get fresh input
- encode endp
-
- ; Fill encode source buffer, report KB and percentage done.
- ; Return carry clear for success
- ; modifies ax
- inbuf proc near
- cmp flags.eoflag,0 ; reached the end?
- je inbuf0 ; e = no
- stc ; return failure
- ret
- inbuf0: push dx
- push bx
- push cx
- mov bx,diskio.handle ; get file handle
- mov cx,buffsz ; record size
- mov dx,offset buff ; buffer
- mov ebufpnt,dx ; buffer pointer
- cmp trans.xtype,1 ; [HF3] File type binary?
- je inbuf0a ; [HF3] e = yes, no translation
- cmp trans.xchset,xfr_japanese ; Japanese-EUC?
- jne inbuf0a ; ne = no
- shr cx,1 ; allow for double char encoding
- mov dx,offset rdbuf ; use this as source buffer
- inbuf0a:mov ah,readf2 ; read a record
- int dos
- jnc inbuf7 ; nc = no error
- mov flags.cxzflg,'X' ; error, set ^X flag
- jmp short inbuf1 ; and truncate the file here
- inbuf7: or ax,ax ; any bytes read?
- jnz inbuf2 ; nz = yes (the number read)
- inbuf1: mov flags.eoflag,1 ; set End-of-File
- mov filflg,0 ; buffer empty
- mov echrcnt,0 ; zero bytes left in buffer
- pop cx
- pop bx
- pop dx
- stc ; failure
- ret
-
- inbuf2: cmp trans.xchset,xfr_japanese ; Japanese-EUC?
- jne inbuf2a ; ne = no
- call jpnread ; revise buffer for Japanese
- inbuf2a:add tfilsz,ax ; total the # bytes transferred so far
- adc tfilsz+2,0 ; it's a double word
- mov echrcnt,ax ; number of chars read from file
- add fsta.fsbyte,ax
- adc fsta.fsbyte+2,0
- mov filflg,1 ; buffer not empty
- test flags.remflg,dserial ; serial display mode?
- jnz inbuf3 ; nz = yes, skip kbyte and % display
- push si
- push ax
- call kbpr ; show kilobytes sent
- call perpr ; show percent sent
- pop ax
- pop si
- ; Character set translation section
- inbuf3: cmp trans.xchset,xfr_xparent ; Transparent transfer char set?
- je inbuf6 ; e = yes, no translation
- cmp trans.xtype,1 ; File Type Binary?
- je inbuf6 ; e = yes, no translation
- cmp trans.xchset,xfr_japanese ; Japanese-EUC?
- je inbuf6 ; e = yes, processed already
- push ax ; save buffer count
- mov cx,ax ; loop counter
- push si
- push di
- call cplatin ; set bx to offset CP to Xfr chr table
- call cpinvert ; check readable vs invertible set
- mov si,offset buff ; scan this buffer
- push es
- mov di,ds
- mov es,di
- mov di,si
- cld
- inbuf4: lodsb ; get a char
- cmp bx,offset icp437L1 ; invertible CP 437 to Latin1?
- jne inbuf4b ; ne = no
- mov ah,al
- cmp ah,127 ; special case?
- jne inbuf4d ; ne = no
- mov al,26 ; 127 to 26
- jmp short inbuf5
- inbuf4d:cmp al,20 ; range for special cases?
- jb inbuf5 ; b = no
- cmp al,21
- ja inbuf5 ; a = no
- mov al,167
- je inbuf5 ; 21 to 167
- mov al,182
- jmp short inbuf5 ; 20 to 182
- inbuf4b:cmp bx,offset icp850L1 ; invertible CP 850 to Latin1?
- jne inbuf4a ; ne = no
- cmp al,28 ; special case?
- jne inbuf4c ; ne = no
- mov al,127 ; 28 to 127
- jmp short inbuf5
- inbuf4c:cmp al,127 ; special case?
- jne inbuf4a
- mov al,26 ; 127 to 26
- inbuf4a:test al,80h ; GRight?
- jz inbuf5 ; z = no
- and al,not 80h ; strip high bit
- xlatb ; translate via bx table
- inbuf5: stosb ; store char
- loop inbuf4 ; do all concerned
- pop es
- pop di
- pop si
- pop ax
- inbuf6: pop cx
- pop bx
- pop dx
- clc ; success
- ret
- inbuf endp
-
- ; Japanese file transfer section (Hirofumi Fujii, keibun@kek.ac.jp)
- ; Read buffer rdbuf to convert from file character set Shift-JIS (Code Page
- ; 932) to transfer character set Japanese-EUC. Double char translation state
- ; is maintained across file buffers. Init dblbyte to 0 before each new file.
- ; Output is written to buff, with byte count in register AX. The output
- ; could be twice the size of the input. [rewritten by jrd]
- jpnread proc near ; [HF] read Japanese from file
- push si
- push di
- push es
- mov cx,ax ; number of chars in source buffer
- mov ax,ds
- mov es,ax
- mov dl,dblbyteflg ; get state info from previous call
- mov ah,dblbyte ; first byte too
- mov si,offset rdbuf ; read from here
- mov di,offset buff ; write to here (avoids overwrites)
- cld
- jpnrea1:lodsb ; get a byte
- or dl,dl ; doing first byte?
- jnz jpnread3 ; nz = no, second of a pair
- cmp al,81h ; is it Kanji?
- jb jpnrea5 ; b = no
- cmp al,0fch
- ja jpnrea5 ; a = no
- cmp al,9fh
- jbe jpnrea2 ; be = yes
- cmp al,0e0h
- jb jpnrea5 ; b = no
- jpnrea2:mov ah,al ; AL is first byte of Kanji, save it
- mov dl,1 ; say ready to do second byte next
- jmp short jpnrea8 ; continue loop
-
- jpnread3:cmp al,40h ; is second byte Kanji?
- jb jpnrea6 ; b = no
- cmp al,0fch
- ja jpnrea6 ; a = no
- cmp al,7eh
- jbe jpnrea4 ; be = yes
- cmp al,80h
- jb jpnrea6 ; b = no
- jpnrea4:call jpnftox ; convert to xfer char code
- jmp short jpnrea6 ; write the pair
-
- jpnrea5:cmp al,0a1h ; Katakana?
- jb jpnrea7 ; b = no
- cmp al,0dfh
- ja jpnrea7 ; a = no
- mov ah,8eh ; set Katakana prefix
- jpnrea6:xchg ah,al ; write two bytes
- stosb ; store first byte
- xchg ah,al ; get second byte into AL again
- jpnrea7:stosb ; store a byte
- xor dl,dl ; say all bytes have been written
- jpnrea8:loop jpnrea1
- mov dblbyteflg,dl ; save state info
- mov dblbyte,ah ; and first char of a pair
- sub di,offset buff ; compute number of bytes written
- mov ax,di ; report new count in AX
- pop es
- pop di
- pop si
- ret
- jpnread endp
-
- ; File character code (Shift-JIS) to xfer character code (EUC) converter.
- ; From Shift-JIS to EUC
- ; if( code1 <= 0x9f )
- ; code1 -= 0x71;
- ; else
- ; code1 -= 0xb1;
- ; code1 = code1 * 2 + 1;
- ; if( code2 > 0x7f ) code2 -= 1;
- ; if( code2 >= 0x9e ){
- ; code2 -= 0x7d;
- ; code1 += 1;
- ; } else
- ; code2 -= 0x1f;
- ; EUC_code1 = (code1 | 0x80);
- ; EUC_code2 = (code2 | 0x80);
- ; [ fputc( EUC_code1, packet ); fputc( EUC_code2, packet ); ]
- ;
- jpnftox proc near
- cmp ah,9fh
- ja jpnftox1
- sub ah,71h
- jmp short jpnftox2
- jpnftox1:sub ah,0b1h
- jpnftox2:shl ah,1
- inc ah
- cmp al,7fh
- jbe jpnftox3
- dec al
- jpnftox3:cmp al,9eh
- jb jpnftox4
- sub al,7dh
- inc ah
- jmp jpnftox5
- jpnftox4:sub al,1fh
- jpnftox5:or ax,8080h
- ret
- jpnftox endp
-
- ; GETFIL, called only by send code
- ; Enter with raw filename pattern in diskio.string
- ; Returns carry clear if success, else carry set
- getfil proc near
- mov dblbyteflg,0 ; clear encoder state variable
- mov shiftstate,0 ; locking shift state
- mov DLEseen,0 ; escape state
- mov filflg,0 ; say nothing is in the buffer
- mov flags.eoflag,0 ; not the end of file
- mov dx,offset diskio.dta ; data transfer address
- mov ah,setdma ; set disk transfer address
- int dos
- xor cx,cx ; attributes: find only normal files
- mov dx,offset diskio.string ; filename string (may have wild cards)
- mov ah,first2 ; DOS 2.0 search for first
- int dos ; get file's characteristics
- pushf ; save c flag
- mov ah,setdma ; reset dta address
- mov dx,offset buff ; restore dta
- int dos
- popf ; restore status of search for first
- jnc getfi1 ; nc = ok so far
- ret ; else take error exit
- getfi1: jmp getfcom ; do common code
- getfil endp
-
-
- ; GTNFIL called by send code to get next file.
- ; Returns carry clear for success, carry set for failure.
- gtnfil proc near
- mov dblbyteflg,0 ; clear encoder state variable
- mov shiftstate,0 ; locking shift state
- mov DLEseen,0 ; escape state
- cmp flags.cxzflg,'Z' ; Did we have a ^Z?
- jne gtnfi1 ; ne = no, else done sending files
- stc ; carry set for failure
- ret ; take failure exit
-
- gtnfi1: xor al,al
- mov filflg,al ; nothing in the DMA
- mov flags.eoflag,al ; not the end of file
- mov dx,offset diskio.dta ; point at dta
- mov ah,setdma ; set the dta address
- int dos
- mov ah,next2 ; DOS 2.0 search for next
- int dos
- pushf ; save carry flag
- mov ah,setdma ; restore dta
- mov dx,offset buff
- int dos
- popf ; recover carry flag
- jnc getfcom ; nc = success, do common code
- ret ; carry set means no more files found
- gtnfil endp
- ; worker for getfil, gtnfil
- getfcom proc near
- push si
- push di
- mov dx,offset diskio.string ; original file spec (may be wild)
- mov di,offset templp ; place for path part
- mov si,offset templf ; place for filename part
- call fparse ; split them
- mov si,offset diskio.fname ; current filename from DOS
- call strcat ; (di)= local path + diskio.fname
- mov di,offset encbuf ; name to send to host (no path)
- call strcpy ; new string = old path + DOS's filename
- push bx
- push cx
- test flags.remflg,dquiet ; quiet display?
- jnz getfco1 ; e = yes, do not display filename
- call clrfln ; position cursor & blank out the line
- mov dx,offset templp
- call prtasz
- getfco1:call newfn ; update encbuf with "send as" name
- pop cx
- pop bx
- mov ah,open2 ; file open
- xor al,al ; 0 = open readonly
- cmp dosnum,300h ; at or above DOS 3?
- jb getfco2 ; b = no, so no shared access
- or al,40h ; open readonly, deny none
- getfco2:mov dx,offset templp ; filename string with path
- int dos
- jc getfco3 ; c = failed to open the file
- mov diskio.handle,ax ; save file handle
- xor ax,ax
- mov tfilsz,ax ; set bytes sent to zero
- mov tfilsz+2,ax
- mov ax,-1 ; get a minus one
- mov oldkbt,ax
- mov oldper,ax
- clc ; carry clear for success
- getfco3:pop si
- pop di
- ret
- getfcom endp
-
- ; Get the file name from the data portion of the F packet or from locally
- ; specified override filename (in auxfile), displays the filename, does any
- ; manipulation of the filename necessary, including changing the name to
- ; prevent collisions. Returns carry clear for success. Failures return
- ; carry set with dx pointing at error message text.
- ; Called by file receive module in mssrcv.asm.
-
- gofil proc near
- mov si,offset decbuf ; filename in packet
- mov di,offset diskio.string ; place where prtfn finds name
- call strcpy ; copy pkt filename to diskio.string
- mov di,offset fsta.xname ; statistics external filespec area
- call strcpy ; record external name
- cmp auxfile,0 ; have override name?
- jne gofil1 ; ne = yes
- cmp flags.xflg,0 ; receiving to screen?
- jne gofil0a ; ne = yes, filename becomes CON
- cmp flags.destflg,1 ; destination is disk?
- je gofil1 ; e = yes
- mov di,offset printer ; assume PRN is local file name
- jb gofil0b ; b = yes
- gofil0a:mov di,offset screen ; use CON (screen) as local file name
- mov flags.xflg,1 ; say receiving to screen
- gofil0b:xchg di,si ; di --> decbuf, si --> file name
- call strcpy ; put local name (si) into decbuf
- mov nmoflg,1 ; say that we have a replacement name
- jmp gofil9 ; final filename is now in 'decbuf'
-
- gofil1: xor ax,ax
- mov nmoflg,al ; assume no override name
- cmp auxfile,al ; overriding name from other side?
- jne gofi1e ; ne = yes
- jmp gofil4 ; e = no, get the other end's filename
- gofi1e: mov nmoflg,1 ; say using an override name
- mov ax,offset auxfile ; get local override filename
- cmp word ptr auxfile+1,003ah; colon+null?(primative drive spec A:)
- je gofil3 ; e = yes, skip screwy DOS response (No Path)
- cmp word ptr auxfile,'..' ; parent directory?
- jne gofi1g ; ne = no
- cmp word ptr auxfile+1,002eh ; dot dot + null?
- je gofi1b ; e = yes, process as directory
- gofi1g: cmp word ptr auxfile,002eh ; dot + null (current dir)?
- je gofi1b ; e = yes, process as directory
- call isfile ; does it exist?
- jnc gofi1f ; nc = file exists
- test filtst.fstat,80h ; serious error?
- jz gofil3 ; z = no, just no such file
- jmp gofi18a ; else quit here
- gofi1f: test byte ptr filtst.dta+21,10H ; subdirectory name?
- jnz gofi1b ; nz = yes
- cmp filtst.fname,2eh ; directory name?
- je gofi1b ; e = yes, process as directory
- cmp auxfile+2,5ch ; a root directory like b:\?
- jne gofi1d ; ne = no. (DOS is not helpful with roots)
- cmp auxfile+3,0 ; and is it terminated in a null?
- je gofi1b ; e = yes, so it is a root spec
- gofi1d: test byte ptr filtst.dta+21,0fh ; r/o, hidden, system, vol label?
- jz gofil3 ; z = no
- jmp gofi18a ; yes. Complain and don't transfer file
- gofi1b: mov dx,offset auxfile ; auxfile is a (sub)directory name
- call strlen ; get its length w/o terminator
- jcxz gofil2 ; zero length
- dec cx ; examine last char
- push bx ; save bx
- mov bx,cx
- add bx,dx
- cmp byte ptr [bx],5ch ; ends in backslash?
- je gofil2 ; e = yes
- cmp byte ptr [bx],2fh ; maybe forward slash?
- je gofil2 ; e = yes
- mov byte ptr [bx + 1],5ch ; no slash yet. use backslash
- mov byte ptr [bx + 2],0 ; plant new terminator
- gofil2: pop bx
-
- gofil3: mov di,offset templp ; local path
- mov si,offset templf ; local filename
- mov dx,offset auxfile ; local string
- call fparse ; split local string
- mov di,offset temprp ; remote path
- mov si,offset temprf ; remote file
- mov dx,offset decbuf ; remote string
- mov decbuf+64,0 ; force filename to be <= 64 chars
- call fparse ; split remote string
- test flags.remflg,dserver ; running in Server mode?
- jz gofi3c ; z = no
- test denyflg,sndflg ; is Deny Send mode in operation?
- jz gofi3c ; z = no
- mov temprp,0 ; DENY, means remove remote path
- gofi3c: mov si,offset templp ; copy local path to
- mov di,offset decbuf ; final filename
- call strcpy ; do the copy
- mov si,offset templf ; assume using local file name
- cmp byte ptr templf,0 ; local file name given?
- jne gofi3b ; ne = yes
- mov si,offset temprf ; else use remote file name
- gofi3b: call strcat ; append path and filename again
- ; offset decbuf holds the new filename
- ;
- ; recheck legality of filename in 'decbuf'
- gofil4: mov decbuf+64,0 ; guard against long filenames
- mov di,offset temprp ; remote path
- mov si,offset temprf ; remote file
- mov dx,offset decbuf ; remote string
- call strlen ; get original size
- push cx ; remember it
- call fparse ; further massage filename
- push si ; put pieces back together
- call verfil ; verify each char in temprf string
- mov si,di ; get path part first
- mov di,dx ; set destination
- call strcpy ; copy in path part
- pop si ; recover (new) filename
- cmp byte ptr [si],'.' ; does filename part start with a dot?
- jne gofil5 ; ne = no
- push di ; save regs
- push si
- mov di,offset rdbuf ; a work area
- mov byte ptr [di],'X' ; start name with letter X
- inc di
- call strcpy ; copy rest of filename
- mov di,si
- mov si,offset rdbuf ; copy new name back to original location
- call strcpy
- pop si ; restore regs
- pop di
- gofil5: call strcat ; append it
- call strlen ; see if we chopped out something
- pop si ; get original length (from push cx above)
- cmp cx,si ; same size?
- je gofil9 ; e = yes
- mov nmoflg,1 ; say that we have a replacement name
- ; filename is now in 'decbuf', all converted
- gofil9: test flags.remflg,dquiet ; quiet display mode?
- jnz gofi10 ; nz = yes, don't print it
- test flags.remflg,dserial ; serial display mode?
- jz gofi9a ; z = no
- mov ah,prstr
- mov dx,offset crlf ; display cr/lf
- int dos
- gofi9a: call prtfn ; show packet filename
- cmp nmoflg,0 ; using local override name?
- je gofil9b ; e = no
- cmp flags.xflg,0 ; receiving to screen? (X versus F)
- jne gofil9b ; ne = yes
- mov ah,prstr
- mov dx,offset asmsg ; print " as "
- int dos
- mov dx,offset decbuf ; plus the local filename
- call prtasz ; print asciiz string
- gofil9b:mov ah,flags.remflg ; display a following cr/lf?
- and ah,dserial ; for serial display mode
- or ah,flags.xflg ; receiving to screen
- jz gofi10 ; z = neither, no cr/lf
- mov ah,prstr ; finish the line with cr/lf
- mov dx,offset crlf
- int dos
- gofi10: mov ax,offset decbuf ; point to name
- cmp flags.flwflg,1 ; overwrite existing file?
- jne gofi10b ; ne = no
- jmp gofi16 ; e = yes
- gofi10b:call isfile ; does it exist?
- mov ax,offset decbuf ; reload ptr in case
- jc gofi16 ; carry set = no, just proceed
- mov ah,open2 ; could it be a device name?
- xor al,al ; open readonly
- cmp dosnum,300h ; above DOS 2?
- jb gofi10a ; b = no, so no shared access
- or al,40h ; open for reading, deny none
- gofi10a:mov dx,offset decbuf ; the filename
- int dos
- jc gofi11 ; c = cannot open so just proceed
- mov bx,ax ; file handle
- mov ah,ioctl
- xor al,al ; 0 = get info
- int dos
- mov ah,close2 ; close it
- int dos
- mov ax,offset decbuf ; point to filename again
- test dl,80h ; ISDEV bit set?
- jz gofi11 ; z = no, not a device
- jmp gofi16 ; device, use name as given
- gofi11: cmp flags.flwflg,4 ; no-supersede existing file?
- jne gofi12 ; ne = no (i.e., do a rename)
- mov flags.cxzflg,'X' ; say stop this file
- mov word ptr decbuf,'UN'
- mov decbuf+2,'L' ; file name of NUL
- mov decbuf+3,0 ; asciiz
- jmp short gofi13
- gofi12: mov ax,offset decbuf ; point to filename again
- call unique ; generate unique name
- jc gofi14 ; could not generate a unique name
- test flags.remflg,dquiet ; quiet display mode?
- jnz gofi13 ; nz = yes, skip printing
- push ax ; save unique name again
- call frpos ; position cursor
- mov ah,prstr ; say we are renaming the file
- mov dx,offset infms5
- int dos
- pop ax ; get name back into ax again
- push ax ; save around these calls
- mov dx,ax ; print current filename
- call prtasz ; display filename
- pop ax ; pointer to name, again
- gofi13: jmp short gofi16 ; and go handle file
-
- gofi14: mov dx,offset ermes4
- call ermsg
- stc ; failure, dx has msg pointer
- ret
-
- gofi16: mov si,ax ; pointer to (maybe new) name
- mov di,offset diskio.string ; filename, used in open
- mov dx,di ; for isfile and open below
- call strcpy ; copy name to diskio.string
- xor ax,ax
- mov diskio.sizehi,ax ; original file size is unknown
- mov diskio.sizelo,ax ; double word
- mov tfilsz,ax ; set bytes received to zero
- mov tfilsz+2,ax
- mov ax,-1 ; get a minus one
- mov oldkbt,ax
- mov oldper,ax
- clc ; finished composing filename
- ret ; in diskio.string
- ; Come here to formally open the file
-
- gofi18a:mov si,ax ; pointer to local override name
- mov di,offset diskio.string ; filename, used in open
- call strcpy ; copy name to diskio.string
- ; fall through to gofi18
- gofi18: test flags.remflg,dquiet ; quiet display mode?
- jnz gofi19 ; nz = yes, don't try printing
- mov dx,offset erms12 ; unable to create file
- call ermsg
- push dx
- mov dx,offset diskio.string ; print offending name
- call prtasz ; display filename
- pop dx
- gofi19: stc ; failure, dx has msg pointer
- ret
- gofil endp
-
- ; Open file for writing with name in diskio.string
- goopen proc near
- mov dblbyteflg,0 ; clear decoder state variable
- mov shiftstate,0 ; locking shift state
- mov DLEseen,0 ; escape state
- mov dx,offset diskio.string ; filename, asciiz
- mov diskio.handle,0 ; clear handle of previous usage
- mov ax,dx ; filename for isfile
- call isfile ; check for read-only/system/vol-label/dir
- jc goopen1 ; c = file does not exist
- test byte ptr filtst.dta+21,1fh ; the no-no file attributes
- jnz gofi18 ; nz = do not write over one of these
- goopen1:test filtst.fstat,80h ; access problem?
- jnz gofi18 ; nz = yes, quit here
- mov diskio.handle,-1 ; clear handle of previous usage
- mov ah,creat2 ; create file
- xor cx,cx ; 0 = attributes bits
- int dos
- jc goopen2 ; c = did not work, try regular open
- mov diskio.handle,ax ; save file handle here
- clc ; carry clear for success
- ret
- goopen2:test byte ptr filtst.dta+21,1bh ; r/o, hidden, volume label?
- jnz gofi18 ; we won't touch these
- mov ah,open2 ; open existing file (usually a device)
- mov al,1+1 ; open for writing
- int dos
- jc gofi18 ; carry set means can't open
- mov diskio.handle,ax ; file handle
- clc ; carry clear for success
- ret
- goopen endp
-
- ; Given incoming filename in 'decbuf'. Verify that each char is legal
- ; (if not change it to an "X"), force max of three chars after a period (dot)
- ; Source is at ds:si (si is changed here).
-
- VERFIL PROC NEAR
- push es ; verify each char in 'data'
- push cx
- push ds
- pop es
- mov havdot,0 ; say no dot found in name yet
- cld
- verfi1: lodsb ; get a byte of name from si
- and al,7fH ; strip any eighth bit
- jz verfi5 ; z = end of name
- cmp al,'.' ; a dot?
- jne verfi2 ; ne = no
- cmp havdot,0 ; have one dot already?
- jne verfi3 ; ne = yes, change to X
- mov byte ptr [si+3],0 ; forceably end filename after 3 char ext
- mov havdot,1 ; say have a dot now
- jmp short verfi4 ; continue
- verfi2: cmp al,3ah ; colon?
- je verfi4
- cmp al,5ch ; backslash path separator?
- je verfi4
- cmp al,2fh ; or forward slash?
- je verfi4
- cmp al,'0'
- jb verfi3 ; see if it's a legal char < '0'
- cmp al,'9'
- jbe verfi4 ; it's between 0-9 so it's OK
- cmp al,'A'
- jb verfi3 ; check for a legal punctuation char
- cmp al,'Z'
- jbe verfi4 ; it's A-Z so it's OK
- cmp al,'a'
- jb verfi3 ; check for a legal punctuation char
- cmp al,'z'
- ja verfi3
- and al,5FH ; it's a-z, capitalize
- jmp short verfi4 ; continue with no change
-
- verfi3: push di ; special char. Is it on the list?
- mov di,offset spchar2 ; list of acceptable special chars
- mov cx,spc2len
- cld
- repne scasb ; search string for input char
- pop di
- je verfi4 ; e = in table, return it
- mov al,'X' ; else illegal, replace with "X"
- mov nmoflg,1 ; say we have a replacement filename
- verfi4: mov [si-1],al ; update name
- jmp short verfi1 ; loop thru rest of name
- verfi5: mov byte ptr[si-1],0 ; make sure it's null terminated
- pop cx
- pop es
- ret
- VERFIL ENDP
-
- ; find a unique filename.
- ; Enter with a pointer to a (null-terminated) filename in ax
- ; Return with same pointer but with a new name (or old if failure)
- ; Success = carry clear; failure = carry set
- ; The idea is to pad out the main name part (8 chars) with ascii zeros and
- ; then change the last chars successively to a 1, 2, etc. until
- ; a unique name is found. All registers are preserved
- ; Make empty main name fields start with letter X, not digit 0
- unique proc near
- push bx
- push cx
- push dx
- push si
- push di
- push es
- push ax ; save address of source string
- mov dx,ds ; make es use ds segment
- mov es,dx
- mov dx,ax ; point at original filename string
- mov di,offset templp ; place for path
- mov si,offset templf ; place for filename
- call fparse ; separate path (di) and filename (si)
- mov dx,di ; point at path part
- call strlen ; put length in cx
- mov si,ax ; point to original string
- add si,cx ; point to filename part
- mov di,offset templf ; destination is temporary location
- xor cx,cx ; a counter
- cld ; set direction to be forward
- uniq1: lodsb ; get a byte
- cmp al,'.' ; have a dot?
- je uniq2 ; e = yes
- or al,al ; maybe null at end?
- jnz uniq3 ; nz = no, continue loop
-
- uniq2: cmp cl,8 ; have we copied any chars before dot?
- jge uniq3 ; ge = all 8
- mov byte ptr [di],'0' ; avoid clobbers; pad with 0's
- or cl,cl ; first char of filename?
- jnz uniq2a ; nz = no
- mov byte ptr [di],'X' ; start name with letter X, not 0
- uniq2a: inc di ; and count the output chars
- inc cl ; and this counter too
- jmp short uniq2 ; continue until filled 8 slots
- uniq3: inc cl ; cl = # char in destination
- stosb ; store the char
- or al,al ; null at end?
- jnz uniq1 ; nz = no, continue copying
-
- mov templf+7,'1' ; put '1' in last name char
- mov unum,1 ; start with this generation digit
-
- uniq4: mov di,offset rdbuf ; build a temporary full filename
- mov si,offset templp ; path part
- call strcpy ; copy that much
- mov si,offset templf ; get rebuilt filename part
- call strcat ; paste that to the end
- mov ax,offset rdbuf ; point to full name
- call isfile ; does it exist?
- jc uniq6 ; c = no, succeed now
-
- inc unum ; move to next generation
- mov di,offset templf+7 ; point to last name char
- mov cx,7 ; max # of digits to play with
- mov bx,10 ; divisor (16 bits)
- mov ax,unum ; low order part of generation #
- uniq5: xor dx,dx ; high order part of generation #
- div bx ; compute digit (unum / 10)
- add dl,'0' ; make remainder part printable
- mov [di],dl ; put into right place
- or ax,ax ; any more to do? (quotient nonzero)
- jz uniq4 ; z = no, try this name
- dec di ; else decrement char position
- loop uniq5 ; and keep making a number
- stc ; failure: set carry, keep old name
- jmp short uniq7 ; and exit
-
- uniq6: pop di ; address of original filename
- push ax ; save for exit clean up
- mov si,offset rdbuf
- call strcpy ; copy new filename over old
- clc ; success: clear carry flag
- uniq7: pop ax
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- ret
- unique endp
-
-
- ; strlen -- computes the length, excluding the terminator, of an asciiz
- ; string. Input: ds:dx = address of the string
- ; Output: cx = the byte count
- ; All registers except cx are preserved
- ;
- STRLEN PROC NEAR
- push di
- push es
- push ax
- mov ax,ds ; use proper segment address
- mov es,ax
- mov di,dx
- mov cx,0ffffh ; large byte count
- cld ; set direction to be forward
- xor al,al ; item sought is a null
- repne scasb ; search for it
- add cx,2 ; add for -1 and auto dec in scasb
- neg cx ; convert to count, excluding terminator
- pop ax
- pop es
- pop di
- ret
- STRLEN ENDP
-
- ; strcat -- concatenates asciiz string 2 to the end of asciiz string 1
- ; offset of string 1 is expected to be in ds:di. input & output
- ; offset of string 2 is expected to be in ds:si. input only (unchanged)
- ; Preserves all registers. No error returns, returns normally via ret
- ;
- STRCAT PROC NEAR
- push di ; save work registers
- push si
- push es
- push dx
- push cx
- push ax
- mov ax,ds ; get data segment value
- mov es,ax ; set es to ds for implied es:di usage
- mov dx,di
- call strlen ; get length (w/o terminator) of dest string
- add di,cx ; address of first terminator
- mov dx,si ; start offset of source string
- call strlen ; find its length too (in cx)
- inc cx ; include its terminator in the count
- cld
- rep movsb ; copy source string to end of output string
- pop ax
- pop cx
- pop dx
- pop es
- pop si
- pop di
- ret
- STRCAT ENDP
-
- ; strcpy -- copies asciiz string pointed to by ds:si into area pointed to by
- ; ds:di. Returns via ret. All registers are preserved
- ;
- STRCPY PROC NEAR
- cmp si,di ; same place?
- jne strcpy1 ; ne = no
- ret ; having done nothing
- strcpy1:mov byte ptr [di],0 ; clear destination string
- call strcat ; let strcat do the real work
- ret
- STRCPY ENDP
-
- ; fparse -- separate the drive:path part from the filename.ext part of an
- ; asciiz string. Characters separating parts are \ or / or :
- ; Inputs: asciiz input full filename string offset in ds:dx
- ; asciiz path offset in ds:di
- ; asciiz filename offset in ds:si
- ; Outputs: the above strings in the indicated spots
- ; Strategy is simple. Reverse scan input string until one of the
- ; three separators is encountered and then cleave at that point
- ; Simple filename construction restrictions added 30 Dec 1985;
- ; to wit: mainname limited to 8 chars or less,
- ; extension field limited to 3 chars or less and is found by searching
- ; for first occurence of a dot in the filename field. Thus the whole
- ; filename part is restricted to 12 (8+dot+3) chars plus a null
- ; All registers are preserved. Return is always via ret
- ; (Microsoft should have written this for DOS 2.x et seq.)
-
- FPARSE PROC NEAR
- push cx ; local counter
- push ax ; local work area
- push es ; implied segment register for di
- push di ; offset of path part of output
- push si ; offset of file name part of output
- mov ax,ds ; get data segment value
- mov es,ax ; set es to ds for implied es:di usage
- mov byte ptr [si],0 ; clear outputs
- mov byte ptr [di],0
-
- push si ; save original file name address
- mov si,dx ; get original string address
- call strcpy ; copy string to original di
- call strlen ; find length (w/o terminator), in cx
- mov si,di ; address of string start
- add si,cx
- dec si ; si = address of last non-null char
- jcxz fpars5 ; if null skip the path scan
- ; now find last path char, if any
- ; start at the end of input string
- std ; set direction to be backward
- fpars4: lodsb ; get a byte (dec's si afterward)
- cmp al,5ch ; is it a backslash ('\')?
- je fpars6 ; e = yes
- cmp al,2fh ; or forward slash ('/')?
- je fpars6 ; e = yes
- cmp al,3ah ; or even the drive terminator colon?
- je fpars6 ; e = yes
- loop fpars4 ; else keep looking until cx == 0
- ; si is at beginning of file name
- fpars5: dec si ; dec for inc below
- fpars6: inc si
- inc si ; si now points at first filename char
- ; cx holds number of path chars
- ; get original file name address (si)
- pop di ; and make it place to copy filename
- cld ; reset direction to be forward
- mov ax,si ; ax holds filename address for awhile
- push dx
- mov dx,si ; strlen wants string pointer in dx
- call strlen ; get length of filename part into cx
- pop dx
- jcxz fpar7a ; any chars to look at? z = no
- fpars7: cmp byte ptr [si],'.' ; look for a dot in filename
- je fpars8 ; e = found one
- inc si ; look at next filename char
- loop fpars7 ; keep looking until cx = zero
- fpar7a: mov si,ax ; no dot. recover starting address
- mov byte ptr [si+8],0 ; forcably truncate mainname to 8 char
- call strcpy ; copy this part to filename field
- jmp short fparsx ; and exit
- fpars8: mov byte ptr [si+4],0 ; plant terminator after dot + 3 ext chars
- mov cx,si
- sub cx,ax ; cx now = number of chars in mainname field
- cmp cx,9 ; more than 8?
- jb fpars9 ; b = no, we're safe
- mov cx,8 ; limit ourselves to 8 chars in mainname
- fpars9: push si ; remember address of dot and extension
- mov si,ax ; point to start of input filename
- rep movsb ; copy cx chars from si to di (output)
- mov byte ptr [di],0 ; plant terminator where dot goes
- pop si ; source = dot and extension address
- call strcat ; append the dot & ext to the filename field
- fparsx: mov si,ax ; recover start of filename in input string
- mov byte ptr [si],0 ; terminate path field
- pop si
- pop di
- pop es
- pop ax
- pop cx
- ret
- FPARSE ENDP
-
- ; Print filename in offset diskio.string.
- PRTFN PROC NEAR
- test flags.remflg,dquiet ; quiet display mode?
- jnz prtfn1 ; nz = yes, don't display filename
- push ax ; saves for messy clrfln routine
- push bx
- push dx
- call clrfln ; position cursor & blank out the line
- mov dx,offset diskio.string
- call prtasz
- pop dx
- pop bx
- pop ax
- prtfn1: ret
- PRTFN ENDP
-
-
- ; Print string to screen from offset ds:di for # bytes given in cx,
- ; regardless of $'s. All registers are preserved.
-
- PRTSCR PROC NEAR
- jcxz prtscr4 ; cx = zero means nothing to show
- push ax
- push bx
- push dx
- mov dx,di ; source ptr for DOS
- cmp flags.eofcz,0 ; end on Control-Z?
- jne prtscr3 ; ne = yes, let DOS do it
- push cx ; else map Control-Z to space
- push di
- push es
- push ds
- pop es ; data to es
- mov al,ctlz ; look for Control-Z
- cld ; scan buffer es:di, cx chars worth
- prtscr1:repne scasb
- jne prtscr2 ; ne = found no Control-Z's
- mov byte ptr [di-1],' ' ; replace Control-Z with space
- jcxz prtscr2 ; z = examined all chars
- jmp short prtscr1 ; until examined everything
- prtscr2:pop es
- pop di
- pop cx
- prtscr3:mov bx,1 ; stdout file handle
- mov ah,write2
- int dos
- pop dx
- pop bx
- pop ax
- prtscr4:ret
- PRTSCR ENDP
-
- ; Print to screen asciiz string given in ds:dx. Everything preserved.
- PRTASZ PROC NEAR
- push cx
- push di
- call strlen ; get length of asciiz string
- mov di,dx ; where prtscr looks
- call prtscr ; print counted string
- pop di
- pop cx
- ret
- PRTASZ ENDP
-
- ;;; Load a translation table for file transfer
- load proc near
- ;; mov dx,offset loadtab ; keyword Transfer-character-set
- ;; xor bx,bx ; help
- ;; mov ah,cmkey
- ;; call comnd
- ;; jnc load0
- ;; ret
- ;;load0: mov dx,offset rdbuf ; buffer for filename
- ;; mov word ptr rdbuf,0
- ;; mov bx,offset loadhlp ; help
- ;; mov ah,cmword
- ;; call comnd ; get filename
- ;; jnc load1 ; nc = success
- ;; ret ; failure
- ;;load1: mov ax,offset rdbuf ; place for filename for isfile
- ;; call isfile ; does file exist?
- ;; jnc load1b
- ;;load1a: mov dx,offset infms6 ; unable to open file
- ;; mov ah,prstr
- ;; int dos
- ;; stc
- ;; ret ; c = does not exist
- ;;load1b: mov dx,ax
- ;; mov cx,134
- ;; mov ah,open2 ; file open
- ;; xor al,al ; 0 = open readonly
- ;; cmp dosnum,300h ; at or above DOS 2?
- ;; jb load2 ; b = no, so no shared access
- ;; or al,40h ; open readonly, deny none
- ;;load2: int dos
- ;; jc load1a ; if carry then error
- ;; mov diskio.handle,ax ; file handle
- ;; ; read and parse lines
- ;; mov linecnt,0 ; line counter
- ;; call readln ; L1, read and discard table name
- ;; jc load5 ; c = failure
- ;; call readln ; L2, COMMON or LOCAL
- ;; jc load5 ; c = failure
- ;; mov ax,word ptr rdbuf
- ;; or ax,2020h ; to lower case
- ;; mov tblptr,offset userin
- ;; cmp ax,'oc' ; "common"? (on the wire to local)
- ;; je load4 ; e = yes
- ;; mov tblptr,offset userout
- ;; cmp ax,'ol' ; "local"? (local to on the wire)
- ;; jne load5 ; ne = no, fail
- ;;
- ;;load4: call readln ; L3 name of comms line char set
- ;; jnc load6 ; success
- ;;load5: jmp loadx
- ;;
- ;;load6: call readln ; L4 bytes per char in above set
- ;; jc load5
- ;; mov si,offset rdbuf ; text, ah has char count
- ;; call atoi ; ax has value
- ;; jc load5 ; c = no number
- ;; cmp ax,1 ; one byte per char?
- ;; jne load5 ; ne = no, fail here
- ;;
- ;; call readln ; L5 chars/plane (94/96/128)
- ;; jc load7 ; c = failure
- ;; mov dx,offset rdbuf
- ;; call strlen
- ;; mov ah,cl
- ;; mov si,offset rdbuf ; text, ah has char count
- ;; call atoi ; ax has value
- ;; jc load7 ; c = no number
- ;; cmp ax,128 ; too many?
- ;; ja load7 ; a = yes, fail here
- ;;
- ;; call readln ; L6 name of local display char set
- ;; jnc load8
- ;;load7: jmp loadx
- ;;
- ;;load8: call readln ; L7 bytes per char in above set
- ;; jc load7
- ;; mov dx,offset rdbuf
- ;; call strlen
- ;; mov ah,cl
- ;; mov si,offset rdbuf ; text, ah has char count
- ;; call atoi ; ax has value
- ;; jc load7 ; c = no number
- ;; cmp ax,1 ; one byte per char?
- ;; jne load7 ; ne = no, fail here
- ;;
- ;; call readln ; L8 chars/plane (94/96/128)
- ;; jc load7 ; failure
- ;; mov dx,offset rdbuf
- ;; call strlen
- ;; mov ah,cl
- ;; mov si,offset rdbuf ; text, ah has char count
- ;; call atoi ; ax has value
- ;; jc load7 ; c = no number
- ;; cmp ax,128 ; too many?
- ;; ja load7 ; a = yes, fail here
- ;;
- ;; call readln ; L9 designator of comms line set
- ;; jc load8
- ;; call readln ; L10 Version of comms line set
- ;; jc load8
- ;; call readln ; L11 Registration num of comms set
- ;; jc load8
- ;; call readln ; L12 direction of writing
- ;; jc load8
- ;; call readln ; L13 number of entries in table below
- ;; jc load7
- ;; mov dx,offset rdbuf
- ;; call strlen
- ;; mov ah,cl
- ;; mov si,offset rdbuf ; text, ah has char count
- ;; call atoi ; ax has value
- ;; jc load7 ; c = no number
- ;; mov xlines,ax
- ;;
- ;; call readln ; L14 count of filler lines before
- ;; jc load7 ; table below
- ;; mov dx,offset rdbuf
- ;; call strlen ; length to cx
- ;; mov ah,cl
- ;; mov si,offset rdbuf ; text, ah has char count
- ;; call atoi ; ax has value
- ;; jc load7 ; c = no number
- ;; mov cx,ax ; count of filler lines
- ;; jcxz load10 ; z = none
- ;;load9: push cx
- ;; call readln ; L15 et seq, filler lines
- ;; pop cx ; read and discard
- ;; jc loadx
- ;; loop load9
- ;;
- ;;load10: dec xlines ; Translation data lines
- ;; cmp xlines,0 ; any left?
- ;; jge load11 ; ge = yes
- ;; jmp loady
- ;;load11: call readln ; translation table line(s)
- ;; jc loadx ; c = failure
- ;; mov si,offset rdbuf ; the buffer
- ;; mov dx,si
- ;; call strlen ; length to cx
- ;; mov ah,cl ; count for atoi
- ;; call atoi ; get "from" number
- ;; jc loadx ; failure
- ;; test al,80h ; referring to high bit set (GR)?
- ;; jnz load12 ; nz = yes
- ;; jmp loadx
- ;;load12: and ax,not 0ff80h ; strip bit for GR table
- ;; mov temp,ax ; save here
- ;; mov dx,si
- ;; call strlen
- ;; mov ah,cl ; count
- ;; call atoi ; get "to" number
- ;; mov bx,tblptr ; point at table
- ;; add bx,temp ; locate entry
- ;; mov [bx],al ; store new value
- ;; jmp load10 ; repeat til done
- ;;
- ;;loadx: mov dx,offset badvalue ; complain
- ;; mov ah,prstr
- ;; int dos
- ;; mov ax,linecnt ; show line number
- ;; call decout
- ;; mov ah,conout
- ;; mov dl,':'
- ;; int dos
- ;; mov dx,offset rdbuf ; show the line
- ;; call prtasz
- ;;loady: mov bx,diskio.handle
- ;; mov ah,close2 ; close the file
- ;; int dos
- clc
- ret
- load endp
- ;;
- ;;readln proc near
- ;; push ax
- ;; push bx
- ;; push cx
- ;; push dx
- ;; push di
- ;; inc linecnt ; line counter
- ;; mov cx,82 ; 82 bytes, including trailer
- ;; mov temp,0 ; leading whitespace and comment flgs
- ;; mov di,offset rdbuf ; destination buffer
- ;; mov bx,diskio.handle ; file handle
- ;;readln1:push cx ; read from file
- ;; mov cx,1 ; read 1 char
- ;; mov dx,di ; place here
- ;; mov byte ptr [di],0 ; insert terminator
- ;; mov ah,readf2
- ;; int dos
- ;; pop cx
- ;; jc readlnx ; c = read failure
- ;; or ax,ax ; count of bytes read
- ;; jz readlnx ; z means end of file
- ;; cmp byte ptr [di],LF ; LF?
- ;; je readln3 ; e = yes, ignore it
- ;; cmp byte ptr [di],CR ; end of line?
- ;; je readln4 ; e = yes, exit
- ;; cmp byte ptr [di],';' ; start of comment?
- ;; jne readln6 ; ne = no
- ;; mov byte ptr temp+1,1 ; say comment has started
- ;; jmp short readln3 ; do not store it
- ;;readln6:cmp byte ptr temp+1,0 ; seen comment semicolon yet?
- ;; jne readln3 ; ne = yes, do not store comment
- ;; cmp byte ptr temp,0 ; seen non-spacing char yet?
- ;; jne readln2 ; ne = yes
- ;; cmp byte ptr [di],' ' ; is this a space?
- ;; je readln3 ; e = yes, skip it
- ;; cmp byte ptr [di],TAB ; or a tab?
- ;; je readln3 ; e = yes, skip it
- ;; mov byte ptr temp,1 ; say have seen non-spacing char
- ;;readln2:cmp flags.takflg,0 ; echo Take files?
- ;; je readln2a ; e = no
- ;; mov ah,conout
- ;; mov dl,byte ptr [di]
- ;; int dos
- ;;readln2a:inc di ; next storage cell
- ;;readln3:loop readln1 ; loop til end of line
- ;;readln4:cmp flags.takflg,0 ; echo Take files?
- ;; je readln4a ; e = no
- ;; mov ah,prstr
- ;; mov dx,offset crlf
- ;; int dos
- ;;readln4a:clc
- ;; mov byte ptr [di],0 ; insert final terminator
- ;; jmp short readlnx
- ;;
- ;;readln5:stc ; set carry for failure to read
- ;;readlnx:pop di
- ;; pop dx
- ;; pop cx
- ;; pop bx
- ;; pop ax
- ;; ret
- ;;readln endp
- code ends
- end
-